簡體   English   中英

對象數組上的 Javascript reduce(),條目也是簡單變量和數組

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM