Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

275
Visualizações
Merge an array by comparing the array of objects inside the array

I have the following array

    var array = [
        {
            group: "FL",
            list: [
                { key: "A", value: "Alaska" },
                { key: "B", value: "Brazil" },
                { key: "C", value: "California" }
            ]
        },
        {
            group: "NZ",
            list: [
                { key: "A", value: "Alaska" },
                { key: "B", value: "Brazil" },
                { key: "D", value: "Delhi" }
            ]
        },
        {
            group: "QA",
            list: [
                { key: "A", value: "Alaska" },
                { key: "B", value: "Brazil" },
                { key: "C", value: "California" }
            ]
        }
    ]

I need to check the list array and if all the objects in the list array are exately same , then I need to merge it as below:

    [
        {
            group: "FL,QA",
            list: [
                { key: "A", value: "Alaska" },
                { key: "B", value: "Brazil" },
                { key: "C", value: "California" }
            ]
        },
        {
            group: "NZ",
            list: [
                { key: "A", value: "Alaska" },
                { key: "B", value: "Brazil" },
                { key: "D", value: "Delhi" }
            ]
        }
    ]

I tried this by using reduce method to loop over the array and two other functions to compare the objects, but somehow its not working

    array.reduce(async(acc, item) => {
        const exist = await compareObjects(acc, item);
        if (exist) {
            acc[exist.index].group= exist.group + ',' + item.group;
        } else {
            acc.push(item)
        }
      return acc;
    }, [])
    async function compareObjects(o1, o2) {
        for (let i = 0; i < o1.length; i++) {
           const value = await checkObjs(o1[i].list, o2.list);
            if(value) { return {index:i  , group: o1[i].group} }
        }
    }

    function checkObjs(arr1, arr2) {
        return arr1.length === arr2.length && arr1.every((el, i) => objectsEqual(el, arr2[i]))
    }

    const objectsEqual = (o1, o2) =>
        Object.keys(o1).length === Object.keys(o2).length
        && Object.keys(o1).every(p => o1[p] === o2[p]);

Any help would be appreciated . Thanks

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

Your use of async is what's tripping you up here, and I'm not sure your reason for using it.

To make your code work as is you need to await the accumulator on each iteration, and assign the result of the reduce() to something.

var array = [ { group: 'FL', list: [ { key: 'A', value: 'Alaska' }, { key: 'B', value: 'Brazil' }, { key: 'C', value: 'California' }, ], }, { group: 'NZ', list: [ { key: 'A', value: 'Alaska' }, { key: 'B', value: 'Brazil' }, { key: 'D', value: 'Delhi' }, ], }, { group: 'QA', list: [ { key: 'A', value: 'Alaska' }, { key: 'B', value: 'Brazil' }, { key: 'C', value: 'California' }, ], }, ];

function checkObjs(arr1, arr2) {
  const objectsEqual = (o1, o2) =>
    Object.keys(o1).length === Object.keys(o2).length && Object.keys(o1).every((p) => o1[p] === o2[p]);

  return arr1.length === arr2.length && arr1.every((el, i) => objectsEqual(el, arr2[i]));
}

async function compareObjects(o1, o2) {
  for (let i = 0; i < o1.length; i++) {
    const value = await checkObjs(o1[i].list, o2.list);
    if (value) {
      return { index: i, group: o1[i].group };
    }
  }
}

// assign the result of reduce to a variable
const result = array.reduce(async (acc, item) => {
  acc = await acc; // await the returned accumulator Promise

  const exist = await compareObjects(acc, item);

  if (exist) {
    acc[exist.index].group = exist.group + ',' + item.group;
  } else {
    acc.push(item);
  }

  return acc;
}, []);

result.then((r) => console.log(r));
.as-console-wrapper { max-height: 100% !important; top: 0; }

about 4 years ago · Juan Pablo Isaza Relatório

0

You can use Array.reduce() to create a map of your input objects.

We'll create a function getListKey() to create a unique key based on each object list.

Once we have our map, we can use Object.values() to get the array result:

var array = [ { group: "FL", list: [ { key: "A", value: "Alaska" }, { key: "B", value: "Brazil" }, { key: "C", value: "California" } ] }, { group: "NZ", list: [ { key: "A", value: "Alaska" }, { key: "B", value: "Brazil" }, { key: "D", value: "Delhi" } ] }, { group: "QA", list: [ { key: "A", value: "Alaska" }, { key: "B", value: "Brazil" }, { key: "C", value: "California" } ] } ]

function getListKey(list) {
    return JSON.stringify(list.sort(({ key: a }, { key: b }) => a.localeCompare(b)));
}

const result = Object.values(array.reduce((acc, { group, list }) => { 
     const key = getListKey(list);
     if (!acc[key]) { 
         acc[key] = { group, list };
     } else {
         acc[key].group += "," + group;
     }
     return acc;
 }, {}))
 
 console.log('Result:', result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Another way of approaching this is again using Array.reduce(), but using the lodash _.isEqual() function for list comparison. This performs a deep comparison. We'd use this along with Array.find() to get any list duplicate.

var array = [ { group: "FL", list: [ { key: "A", value: "Alaska" }, { key: "B", value: "Brazil" }, { key: "C", value: "California" } ] }, { group: "NZ", list: [ { key: "A", value: "Alaska" }, { key: "B", value: "Brazil" }, { key: "D", value: "Delhi" } ] }, { group: "QA", list: [ { key: "A", value: "Alaska" }, { key: "B", value: "Brazil" }, { key: "C", value: "California" } ] } ]

const result = array.reduce((acc, cur) => { 
    const foundItem = acc.find(item => _.isEqual(item.list, cur.list));
    if (foundItem) {
        foundItem.group += `,${cur.group}`;
    } else {
        acc.push(cur);
    }
    return acc;
}, [])

console.log('Result:', result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" referrerpolicy="no-referrer"></script>

about 4 years ago · Juan Pablo Isaza Relatório

0

Reduce does not work with async/await. If you don't have async code - one that fetches something from an API or uses data from a Promise, you should remove the async/await, because it is synchronous.

If the code you have uses some async API - try using something like:

export const reduceAsync = async (array, transformer, initialvalue) => {
    let accumolator = typeof initialValue !== 'undefined' ? initialValue : array[0];

    for (let i = 0; i < array.length; i++) {
        accumolator = await transformer(accumolator, array[i], i, array);
    }

    return accumolator;
};

The function above is reusable and follows the spec defined here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda