Развернуть свойство Array в Object to Multiple Objects, заполненном w / Array value

Этот вопрос назван ужасным, но трудно произнести слова, следующий пример, надеюсь, прояснит ситуацию.

Я все еще изучаю более продвинутые функции Ramda и большую часть своего времени стараюсь сделать это преобразование более кратким в Ramda, но версия ES6 все еще кажется более читаемой и короткой.

Я надеялся, что свист Ramda может помочь выразить эту функцию лучше, используя меньше функций, возможно, короче.

Есть ли лучший способ написать это в Рамде или простой JS?
Спасибо!

Обновление: добавлены некоторые дополнительные свойства для объектов, поскольку целью является сохранение их целостности в новом массиве объектов.

// Для каждого типа в bundle.types создается новый пакет obj. const bundles = [ { name : 'banana' , input : 'src / banana.js' , dir : 'dist' , types : [ 'esm' , 'umd' ] }, { name : 'apple' , input : ' src / apple.js ' , dir : ' dist ' , types : [ ' umd ' ] } ] / * => [{name: 'banana', input: 'src / banana.js', dir: 'dist', type: 'esm'}, {name: 'banana', input: 'src / banana.js ', dir:' dist ', type:' umd '}, {name:' apple ', input:' src / apple.js ', dir:' dist ', type:' umd '}] * / let allBundles = R . цепь ( R . сходится ( R . Труба ( R . xprod , R . карта ( R . mergeAll )), [ R . Труба ( R . dissoc ( 'типы' ), Р . из ), R . труба ( R . проп ( 'типы' ), R . карта ( R . objOf ( 'типа' ))) ] ), пучки ); консоль . log ( 'ramda' ); консоль . войти ( JSON . stringify ( allBundles , нуль , 2 )); allBundles = bundles . reduce (( acc , b ) => { return acc . concat ( b . types . map (( type ) => { const bundle = { ... b , type }; delete bundle . types ; return bundle ; })) ; }, []); консоль . войти ( 'LAMDA' ) консоли . войти ( JSON . stringify ( allBundles , нуль , 2 )); % 28R.converge% 28% 0A% 09R.pipe% 28R.xprod% 2C% 20R. <script src = "https://cdn.jsdelivr.net/npm/ramda@0.25.0/dist/ramda.min.js" > </ script> % 28R.mergeAll% 29% 29% 2C% 0A% 09 % 5B% 0A% 09% 09R.pipe% 28R.dissoc% 28% 27types% 27% 29% 2C% 20R.of% 29% 2C% 0A% 09% 09R.pipe% 28R.prop% 28% 27% 27types % 29% 2C% 20R.map% 28R.objOf% 28% 27type% 27% 29% 29% 29% 0A% 09% 5D% 0A% 29% 2C% 20bundles% 29% 3B% 0A% 0Aconsole.log% 28 % 27ramda% 27% 29% 3B% 0Aconsole.log% 28JSON.stringify% 28allBundles% 2C% 20null% 2C% 202% 29% 29% 3B% 0A% 0AallBundles% 20% 3D% 20bundles.R.chain% 28% 28acc % 2C% 20b% 29% 20% 3D% 3E% 20% 7B% 0A% 09return% 20acc.concat% 28b.types.map% 28% 28type% 29% 20% 3D% 3E% 20% 7B% 0A% 09 % 09const% 20bundle% 20% 3D% 20% 20% 7B ... B% 2C% 20type% 20% 7D% 3B% 0A% 09% 09delete% 20bundle.types% 3B% 0A% 09% 09return% 20bundle% 3B % 0A% 09% 7D% 29% 29% 3B% 0A% 7D% 2C% 20% 5B% 5D% 29% 3B% 0A% 0Aconsole.log% 28% 27lamda% 27% 29% 0Aconsole.log% 28JSON.stringify % 28allBundles% 2C% 20null% 2C% 202% 29% 29% 3B% 0A "rel =" nofollow noreferrer "> Ссылка на Ramda REPL

const bundles = [ { name:  "banana"
                  , input: "src/banana.js"
                  , dir:   "dist"
                  , types: ["esm", "umd"]
                  }
                , { name:  "apple"
                  , input: "src/apple.js"
                  , dir:   "dist"
                  , types: ["umd"]
                  }
                ];

const unbundle = ({ types, ...rest }) =>
    types.map(type => ({ ...rest, type }));

const unbundleAll = R.chain(unbundle);

console.log(JSON.stringify(unbundleAll(bundles), null, 2));
<script src="https://cdn.jsdelivr.net/npm/ramda@0.25.0/dist/ramda.min.js"></script>

javascript,functional-programming,ramda.js,

2

Ответов: 4


3 принят

Это идеальное место для использования R.chain:

const bundles = [ { name:  "banana"
                  , input: "src/banana.js"
                  , dir:   "dist"
                  , types: ["esm", "umd"]
                  }
                , { name:  "apple"
                  , input: "src/apple.js"
                  , dir:   "dist"
                  , types: ["umd"]
                  }
                ];

const unbundle = ({ types, ...rest }) =>
    types.map(type => ({ ...rest, type }));

const concatMap = f => xs => [].concat(...xs.map(f));

const unbundleAll = concatMap(unbundle);

console.log(JSON.stringify(unbundleAll(bundles), null, 2));
const bundles = [
    { name: 'banana', types: ['esm', 'umd'] },
    { name: 'apple', types: ['umd'] }
];

let newArray = [];
bundles.forEach(bundle => {
    bundle.types.map(type => {
      newArray.push({ name: bundle.name, type })
    });
});
console.log(newArray);

This will output =>
[
  {
   "name": "banana",
   "type": "esm"
  },
  {
    "name": "banana",
    "type": "umd"
  },
  {
    "name": "apple",
    "type": "umd"
  }
]

Вот то же самое в vanilla JS:

const allBundles = bundles.reduce(
    (acc, { types, ...attrs}) => 
        [...acc, ...types.map((type) => ({...attrs, type }))], []);

const bundles = [
    { name: 'banana', types: ['esm', 'umd'] }, 
    { name: 'apple', types: ['umd'] },
];

console.log('lamda')
console.log(JSON.stringify(allBundles, null, 2));

Надеюсь, это поможет.


1
<script src="https://cdn.jsdelivr.net/npm/ramda@0.25.0/dist/ramda.min.js"></script>

1

Я не очень хорош в Рамде, но в JS я вижу потенциал:

flaMap
const bundles = [
    {
        name: 'banana',
        types: ['esm', 'umd']
    },
    {
       name: 'apple',
       types: ['umd']
    }
];

const expanded = (arr) => {
    return arr.reduce((o,n)=>{
     let result = n.types.map((t)=>{
      return {name:n.name, type:t}
     });
     o = [...o,...result];
     return o;
    }, []);
}

Это выглядело бы немного лучше reduce.


0

В JS я бы пошел:

map

Вот скрипка .

Объяснение: То, что вы хотите, это массив объектов (поэтому reduceдля сбора результата), которые создаются с помощью коллекции, созданной из mapтипов.

Я не знаю RamdaJS

От взгляда на документацию преобразование с Рамдой с использованием R.Reduce и R.map должно быть непростым.

Для того , чтобы получить типы, можно использовать потроха .

JavaScript, функционально-программирование, ramda.js,
Похожие вопросы