![](/img/trans.png)
[英]How to reduce an array of objects on multiple variables in Javascript?
[英]Javascript reduce() on array of objects, with entries being simple variables and array as well
我正在尝试使用 reduce function 来遍历对象数组并获得 output 总结对象数组内部显示的数据(实际上是一种重复删除器)。
关于数据,例如:
mainData = [
{data : {name: "item1", color: "red", type: ["metal", "wood"]}, id: 1},
{data : {name: "item2", color: "green", type: ["wood"]}, id: 2},
{data : {name: "item3", color: "green", type: ["wood", "stone", "marble"]}, id: 3},
{data : {name: "item4", color: "red", type: ["stone"]}, id: 4}
]
使用 function 时:
const getValues = (data, key) => {
return data.reduce((acc, item) => {
if(acc.indexOf(item.data[key]) > -1) {
return [...acc]
} else {
return [...acc, item.data[key]]
}
}, [data[0].data[key]]) //initial value
}
如果我将此getValues
function getValues(mainData, "color")
称为color
键,它会很好,给出以下 output: ["red", "green"]
,这是预期的。
但是如果我用getValues(mainData, "type")
调用 function,这个 function 将忽略键type
中数组类型值中的大部分值。
我试图通过在 reduce function 的if...else
条件之前使用受data["type"].length
限制的for
循环来解决它,如下所示:
const getValues = (data, key) => {
return data.reduce((acc, item) => {
for(let i = 0; i < item.data[key].length; i++) {
if(acc.indexOf(item.data[key][i]) > -1) {
return [...acc]
} else {
return [...acc, item.data[key][i]]
}
}
}, [data[0].data[key][0]])
}
但它也不起作用。
任何人都知道如何解决这个问题?
你可以为此使用flatMap
像这样
const mainData = [ {data: {name: "item1", color: "red", type: ["metal", "wood"]}, id: 1}, {data: {name: "item2", color: "green", type: ["wood"]}, id: 2}, {data: {name: "item3", color: "green", type: ["wood", "stone", "marble"]}, id: 3}, {data: {name: "item4", color: "red", type: ["stone"]}, id: 4} ] const getValue = (data, key) => [...new Set(data.flatMap(({data}) => Array.isArray(data[key])?data[key]: [data[key]]))] console.log(getValue(mainData, 'name')) console.log(getValue(mainData, 'type'))
使用Set对值进行重复数据删除可能更容易。
const mainData=[{data:{name:"item1",color:"red",type:["metal","wood"]},id:1},{data:{name:"item2",color:"green",type:["wood"]},id:2},{data:{name:"item3",color:"green",type:["wood","stone","marble"]},id:3},{data:{name:"item4",color:"red",type:["stone"]},id:4}]; // Pass in the data, and the prop you want to look at function finder(arr, prop) { // Create a new set const set = new Set(); // Iterate over the array of objects for (const obj of arr) { const value = obj.data[prop]; // If `value` is an array add each value to the set if (Array.isArray(value)) { value.forEach(v => set.add(v)); } else { // Otherwise just add the value set.add(obj.data[prop]); } } // Return an array from the set return [...set]; } console.log(finder(mainData, 'color')); console.log(finder(mainData, 'type')); console.log(finder(mainData, 'name'));
.flatMap()
第一层搜索keyA
(“数据”)。 每个data:{...}
object 被转换成一个对数组:
[["name","item1"],["color","red"],["type",["metal","wood"]],...];
另一个.flatMap()
遍历对数组并在与keyB
匹配时返回一个值。 其他所有内容都作为空数组返回,因为.flatMap()
平它的返回值,所以不会产生任何结果。
([k, v]) => k === keyB? v:[])
最后,将两个flatMap()
的返回值放入Set()
中,然后将Set
作为无重复数组返回。
return [...new Set(output)];
const mainData = [ {data: {name: "item1", color: "red", type: ["metal", "wood"]}, id: 1}, {data: {name: "item2", color: "green", type: ["wood"]}, id: 2}, {data: {name: "item3", color: "green", type: ["wood", "stone", "marble"]}, id: 3}, {data: {name: "item4", color: "red", type: ["stone"]}, id: 4} ]; function compact(objArray, keyA, keyB) { const output = objArray.flatMap( obj => Object.entries(obj[keyA]).flatMap( ([k, v]) => k === keyB? v:[] ) ); return [...new Set(output)]; } console.log(compact(mainData, 'data', 'type')); console.log(compact(mainData, 'data', 'color')); console.log(compact(mainData, 'data', 'name'));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.