简体   繁体   English

如何使用父对象数组中子对象数组的唯一值有效地构造新对象数组

[英]How to efficiently construct new object array using unique values from arrays of children inside an array of parent objects

The need is to take objects like this:需要采取这样的对象:

[ { "first": 
    { "children" : [{ "name": "abc", "detail":"123"},
                  { "name": "def", "detail":"456"}
                 ]
    }},
  { "second": 
    { "children" : [{ "name": "ghi", "detail":"123"},
                  { "name": "jkl", "detail":"456"}
                 ]
    }},
  { "third": 
    { "children" : [{ "name": "mno", "detail":"123"},
                  { "name": "pqr", "detail":"456"}
                 ]
    }},
  { "fourth": 
    { "children" : [{ "name": "stu", "detail":"123"},
                  { "name": "vwx", "detail":"456"}
                 ]
    }},
  { "fifth": 
    { "children" : [{ "name": "yz", "detail":"123"},
                  { "name": "abc", "detail":"456"}
                 ]
    }},
  { "sixth": 
    { "children" : [{ "name": "def", "detail":"123"},
                  { "name": "ghi", "detail":"456"}
                 ]
    }}
]

and then create a flattened array of unique values (options for a select) from the name field of the children that looks like this:然后从子项的 name 字段创建一个扁平化的唯一值数组(选择的选项),如下所示:

[{"value":"abc", "label":"abc"},
 {"value":"def", "label":"def"},
 {"value":"ghi", "label":"ghi"},
 {"value":"jkl", "label":"jkl"},
 {"value":"mno", "label":"mno"},
 {"value":"pqr", "label":"pqr"},
 {"value":"stu", "label":"stu"},
 {"value":"vwx", "label":"vwx"},
 {"value":"yz", "label":"yz"}
]

The code below is working, but it looks like it is inefficient because it appears to make many passes over the array:下面的代码正在运行,但看起来效率低下,因为它似乎对数组进行了多次传递:

[
  ...new Set(
     [].concat.apply([], bases.map((base) => {
       if (!base.children || base.children.length === 0) return;
       return  base.children}
     )).map((child) => child.name)
  )
].map((optName) => {return {value: optName, label: optName};})

If it is possible, how can this same result be achieved without as many iterations across the array.如果可能的话,如何在不跨阵列进行多次迭代的情况下实现相同的结果。

Firstly, as a rule of thumb, you shouldn't worry too much about performance until you have a reason to do so.首先,根据经验,在有理由这样做之前,您不应过分担心性能。

Secondly, chaining the array prototype functions (eg map, forEach, filter) will require multiple iterations by design.其次,按照设计链接数组原型函数(例如 map、forEach、filter)将需要多次迭代。

Thirdly, there's no reason to assume multiple iterations is slower than a single iteration if the work done within the iterations is the same anyways.第三,如果迭代中完成的工作无论如何都相同,则没有理由假设多次迭代比单次迭代慢。 Ie incrementing an index and comparing it with an array length isn't going to be the bottleneck compared to pushing objects into arrays and check set entries.即,与将对象推入数组并检查集合条目相比,增加索引并将其与数组长度进行比较不会成为瓶颈。

Here's a (IMO) cleaner snippet to extract unique names from your array:这是一个(IMO)更清晰的片段,用于从您的数组中提取唯一名称:

 let bases = [{ children: [{ name: "abc", detail: "123" }, { name: "def", detail: "456" } ] }, { children: [{ name: "abc" , detail: "123" }, { name: "xyz" , detail: "456" } ] }, {} ]; let output = bases .flatMap(b => b.children || []) .map(c => c.name) .filter((v, i, a) => a.indexOf(v) === i) // filter unique values .map(name => ({ value: name, label: name, })); console.log(output);

Now if you really want to do all this in a single iteration, that too is possible, but harder to read:现在,如果你真的想在一次迭代中完成所有这些,那也是可能的,但更难阅读:

 let bases = [{ children: [{ name: "abc", detail: "123" }, { name: "def", detail: "456" } ] }, { children: [{ name: "abc" , detail: "123" }, { name: "xyz" , detail: "456" } ] }, {} ]; let output = []; let seenNames = {}; for (base of bases) { if (!base.children) continue; for (child of base.children) { let name = child.name; if (seenNames[name]) continue; seenNames[name] = true; output.push({ value: name, label: name, }); } } console.log(output);

You could take Array#flatMap for getting a flat representation of data for using unique values and map new objects.您可以使用Array#flatMap来获取数据的平面表示,以使用唯一值和映射新对象。

 var data = [{ first: { children: [{ name: "abc", detail: "123" }, { name: "def", detail: "456" }] } }, { second: { children: [{ name: "ghi", detail: "123" }, { name: "jkl", detail: "456" }] } }, { third: { children: [{ name: "mno", detail: "123" }, { name: "pqr", detail: "456" }] } }, { fourth: { children: [{ name: "stu", detail: "123" }, { name: "vwx", detail: "456" }] } }, { fifth: { children: [{ name: "yz", detail: "123" }, { name: "abc", detail: "456" }] } }, { sixth: { children: [{ name: "def", detail: "123" }, { name: "ghi", detail: "456" }] } }], result = Array.from( new Set(data .flatMap(Object.values) .flatMap(({ children }) => children.map(({ name }) => name)) ), value => ({ value, label: value }) ); console.log(result);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

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

相关问题 如何使用另一个对象数组的键和 arrays 数组中的值来构造对象数组? - How to construct an array of objects by using the keys of another array of objects and values from the array of arrays? 单击时从子数组值更新父数组 - Update parent array from children arrays values on click 如何根据 object 值从两个 arrays 创建一个新的对象数组? - How to create a new array of objects from two arrays based on object values? 如何将值从父级复制到数组中的子级 - How to copy values from parent to children in array 从对象数组内的数组返回唯一的数组值 - Return unique array values from an array inside an array of objects 如何构造一个新的 object 数组,其中包含 JavaScript 中另一个对象数组中的一些已删除属性 - How do I construct a new array of object with some deleted properties from another array of objects in JavaScript 在父对象数组中查找唯一对象 - Finding unique objects inside parent array of objects 如何将具有数组作为值的对象转换为对象数组 - How to convert an object with arrays as values to an array of objects JavaScript-如何将所有嵌套数组中的所有对象放入唯一对象的新数组中 - JavaScript - How to put all of the objects from several nested arrays into a new array of unique objects 如何有效地将 object 拆分为数组中的多个对象 - how to split an object to multiple objects inside an array efficiently
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM