Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

188
Vistas
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 ?

about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

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

about 4 years ago · Juan Pablo Isaza Denunciar

0

It maybe easier to use a Set to dedupe the values.

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

about 4 years ago · Juan Pablo Isaza Denunciar

0

  • .flatMap() the first layer searching for keyA ("data"). Each data:{...} object is converted into an array of pairs:

    [["name","item1"],["color","red"],["type",["metal","wood"]],...];
    
  • Another .flatMap() iterates through the array of pairs and returns a value when it gets a match with keyB. Everything else is returned as an empty array that will result in nothing since .flatMap() flattens it's returns.

    ([k, v]) => k === keyB ? v :[])
    
  • Finally, the return of both flatMap()s are made into a Set() then the Set is returned as an array sans duplicates.

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

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda