Skip to content
Advertisement

Javascript reduce() on array of objects, with entries being simple variables and array as well

I’m trying to use the reduce function in order to iterate through an array of objects and to get an output summing up the data shown inside of the array of objects (a kind of duplicate remover in fact).

On data such as :

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

when using the 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
}

It will fork fine if I call this getValues function getValues(mainData, "color") for the color key, giving the following output : ["red", "green"], which is expected.

But if i call the function with getValues(mainData, "type"), this function will ignore most of the values from the array type value from the key type.

I tried to solve it by using a for loop limited by data["type"].length just before the if...else condition of the reduce function, like this :

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

But it does not work either.

Anyone has an idea of how to solve this ?

Advertisement

Answer

you can use flatMap for that

like this

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'))
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement