简体   繁体   English

将对象中的数组属性扩展为使用数组值填充的多个对象

[英]Expand Array property in Object to Multiple Objects populated w/ Array value

This question title is terrible but it's hard to put in words, the following example will hopefully clear things up. 这个问题的标题很糟糕,但是很难用语言表达,下面的例子有望使事情变得清晰起来。

I'm still learning the more advanced functions of Ramda and spent most of my day trying to get this transformation more succinct in Ramda but the ES6 version still feels more readable and short. 我仍在学习Ramda的更高级功能,并花了大部分时间试图使Ramda中的转换更加简洁,但ES6版本仍然感觉更易读和简短。

I was hoping a Ramda whiz could help to express this function in a better way, using less functions, maybe shorter. 我希望Ramda天才能够以更好的方式来表达此功能,使用更少的功能,甚至更短。

Is there a better way to write this in Ramda or plain JS? 有没有更好的方法可以用Ramda或纯JS编写此代码?
Thank you! 谢谢!

Update: added some extra properties to the objects as the intention is to keep those intact in the new array of objects. 更新:为对象添加了一些额外的属性,目的是使这些属性在新的对象数组中保持不变。

Link to Ramda REPL 链接到Ramda REPL

 // For every type in bundle.types creates a new bundle 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.chain(R.converge( R.pipe(R.xprod, R.map(R.mergeAll)), [ R.pipe(R.dissoc('types'), R.of), R.pipe(R.prop('types'), R.map(R.objOf('type'))) ] ), bundles); console.log('ramda'); console.log(JSON.stringify(allBundles, null, 2)); allBundles = bundles.reduce((acc, b) => { return acc.concat(b.types.map((type) => { const bundle = { ...b, type }; delete bundle.types; return bundle; })); }, []); console.log('lamda') console.log(JSON.stringify(allBundles, null, 2)); 
 <script src="https://cdn.jsdelivr.net/npm/ramda@0.25.0/dist/ramda.min.js"></script> 

This is the perfect place to use R.chain : 这是使用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 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> 

Here's the same thing in vanilla JS: 这是香草JS中的同一件事:

 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)); 

Hope that helps. 希望能有所帮助。

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"
  }
]

I'm not good in Ramda, but in JS I see potential: 我在Ramda中不好,但是在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)); 
 <script src="https://cdn.jsdelivr.net/npm/ramda@0.25.0/dist/ramda.min.js"></script> 

This would have looked slightly better with flaMap . 使用flaMap看起来会更好flaMap

In JS I would go for: 在JS中,我会寻求:

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;
    }, []);
}

Here is the fiddle . 这是小提琴

Explanation: What you want is an array, of objects (therefore reduce to collect the result), which are build by a collection built from a map over the types. 说明:您想要的是一个对象数组(因此可以reduce以收集结果),这些对象是由根据类型map生成的集合构建的。

I have no knowledge of RamdaJS 我不知道RamdaJS

From looking at the documentation, a transformation with Ramda using R.Reduce and R.map should be straigthforward. 从文档上看 ,使用R.ReduceR.map进行Ramda的 转换应该很简单。

In order to get the types, you could leverage pluck . 为了获得类型,您可以利用pluck

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如果变量的值与数组对象的属性匹配,则填充和数组 - Populated and array if value of variable matches with property of an array Objects 如何通过嵌套在对象数组的属性中的对象属性的值在对象数组中找到多个索引? - How to find multiple indexes in array of objects by the value of an object property that nests in a property of array of objects? AngularJS使用对象属性对多个对象数组进行排序 - AngularJS order multiple objects array with object property 如何将一个对象数组拆分成多个普通数组,其中每个数组都由一个属性的值填充? - How to split an array of objects into multiple normal arrays where each array is populated by one property's values? 获取对象数组内对象属性的值 - Get value of object property inside array of objects 将对象的属性值添加到对象数组 - Add property value from object to array of objects 从对象数组获取对象属性值 - Get object property value from array of objects 在具有多个属性名称和值的嵌套对象数组中查找对象数组 - find in array of objects with nested array of objects with multiple property name and value 如何比较数组的多个对象中的属性值? - How to compare a property value in multiple objects of an array? 如何根据属性扩展/扩展对象数组 - How to extend/expand array of objects based on property
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM