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

133
Visualizações
Iterating through an object and updating values based on existing values

I have a data json object structured like this:

data: [{
  "aggregate": {
    "path": "/home/page1",
    "query": "name=todd"
  },
  "visits": 4,
  "clicks": 7
},{
  "aggregate": {
    "path": "/home/page1",
    "query": "name=matt"
  },
  "visits": 5,
  "clicks": 17
},{
  "aggregate": {
    "path": "/home/page2",
    "query": ""
  },
  "visits": 4,
  "clicks": 7
},{
  "aggregate": {
    "path": "/home/page3",
    "query": "term=dig"
  },
  "visits": 2,
  "clicks": 20
},{
  "aggregate": {
    "path": "/home/page1",
    "query": "term=dug"
  },
  "visits": 2,
  "clicks": 11
}]

I am looking to end up with an aggregatedObject object like this:

[{
  "path": "/home/page1",
  "visits": 9,
  "clicks": 24
},{
  "path": "/home/page2",
  "visits": 4,
  "clicks": 7
},{
  "path": "/home/page1",
  "visits": 4,
  "clicks": 31
}]

This is what I have so far:

let aggregatedObject = [];

_.each(data, function (item) {

  if (!_.find(aggregatedObject, { path: item.aggregate.path })) {
    aggregatedObject.push({
      path: item.aggregate.path,
      visits: item.visits,
      clicks: item.clicks
    });
    //console.log('not found');

  } else {
    // so lost here

  }
});

What I'm trying to do is if my new object doesn't have an item that matches the item I'm currently iterating through, I push it to the new object. So far I can successfully do this.

However, if I do find an item that matches the path in my new object (ignoring query), I have no idea how to update that item with the sum of the existing item's visits and clicks, and the one I'm iterating through.

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

0

You can group based on path and add visits and clicks for same path using array#reduce.

const data = [{ "aggregate": { "path": "/home/page1", "query": "name=todd" }, "visits": 4, "clicks": 7 },{ "aggregate": { "path": "/home/page1", "query": "name=matt" }, "visits": 5, "clicks": 17 },{ "aggregate": { "path": "/home/page2", "query": "" }, "visits": 4, "clicks": 7 },{ "aggregate": { "path": "/home/page3", "query": "term=dig" }, "visits": 2, "clicks": 20 },{ "aggregate": { "path": "/home/page1", "query": "term=dug" }, "visits": 2, "clicks": 11 }],
    result = Object.values(data.reduce((r, o) => {
      const path = o.aggregate.path;
      r[path] ??= { path, visits: 0, clicks: 0};
      r[path].visits += o.visits;
      r[path].clicks += o.clicks;
      return r;
    },{}));
console.log(result);

about 4 years ago · Juan Pablo Isaza Relatório

0

I think you want to group data based on path, but your example result doesn't do that, it has two entries for "/home/page1" and none for "/home/page3", I'll assume that's just an error in the post.

You need to test to see if path already exists and if not, add a new aggregate object for it, then add clicks and visits.

Looking through the aggregated array every time for path can get expensive if the array gets very large, so consider making an index object of path to aggregated data array so it's just two lookups (once to get the index then another to get the object) rather than searching through the array every time. E.g. (no lodash I'm afraid):

let data = [{
  "aggregate": {
    "path": "/home/page1",
    "query": "name=todd"
  },
  "visits": 4,
  "clicks": 7
},{
  "aggregate": {
    "path": "/home/page1",
    "query": "name=matt"
  },
  "visits": 5,
  "clicks": 17
},{
  "aggregate": {
    "path": "/home/page2",
    "query": ""
  },
  "visits": 4,
  "clicks": 7
},{
  "aggregate": {
    "path": "/home/page3",
    "query": "term=dig"
  },
  "visits": 2,
  "clicks": 20
},{
  "aggregate": {
    "path": "/home/page1",
    "query": "term=dug"
  },
  "visits": 2,
  "clicks": 11
}];

// Map of path to index in aggArr {path: index}
let pathMap = {};

// Get aggregated array data
let aggData = data.reduce((agg, obj) => {
  let path = obj.aggregate.path;
  
  // If not in index, add it and a new aggregation object
  if (!pathMap.hasOwnProperty(path)) {
    pathMap[path] = agg.length;
    agg.push({path: path, visits:0, clicks:0});
  }

  // target is for convenience, add visits and clicks
  let target = agg[pathMap[path]];
  target.visits += obj.visits; 
  target.clicks += obj.clicks;
  return agg;
}, []);

// Show result
console.log(aggData);

about 4 years ago · Juan Pablo Isaza Relatório

0

Map array with initial destructuring, using ES6 spread syntax. Then reduce accounting for paths previously traversed, summing visits and clicks on appropriate path.


 const res = data
     .map(({ aggregate, ...rest }) => ({ path: aggregate.path, ...rest }))
     .reduce((acc, c, i, arr) => {
         let curr = Object.assign({}, c);
         const traversed = acc.some(item => item.hasOwnProperty('path') && item.path === curr.path);
         if (traversed) return acc;

         arr.forEach((v, idx) => {
            if (idx !== i && c.path === v.path) {
               curr = { 
                  ...curr, 
                  visits: v.visits + curr.visits, 
                 clicks: v.clicks + curr.clicks 
                } 
           }
        })

       return [...acc, curr];
    }, [])

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