简体   繁体   中英

How to use javascript to loop through key , values and add up one key's value when the other's match

I have a dataset of records that look like this :

[{
 "d1d":"2015-05-28T00:00:00.000Z",
 "d1h":0,
 "d15m":0,
 "ct":3
},
{
 "d1d":"2015-05-28T00:00:00.000Z",
 "d1h":0,
 "d15m":0,
 "ct":1
}
]

The ct value changes in every record. If d1d, d1h, and d15m are the same in one or more records, I need to combine those records into one with the sum of all the ct values.

I do have jquery, can I use grep for this?

I realize the server side could do a better job of getting me this data , but I have zero control over that.

You don't have to use jQuery for this, vanilla JavaScript will do. I'll show you two solutions to your problem;

Example 1: Abusing Array#reduce as an iterator

var intermediaryArray = [];
dataset.reduce(function(prev, curr) {
  if(prev.d1d === curr.d1d && prev.d1h === curr.d1h && prev.d15m === curr.d15m) {
    intermediaryArray.push({
      d1d: prev.d1d,
      d1h: prev.d1h,
      d15m: prev.d15m,
      ct: prev.ct + curr.ct
    });
  } else {
    // push the one that wasn't the same
    intermediaryArray.push(curr);
  }
  // return current element so reduce has something to work on
  // for the next iteration.
  return curr;
});

Example 2: Using Array#Map and Array#Reduce in conjunction

This example utilises underscore.js to demonstrate the logic behind what you want to do.

.map() produces the new array of grouped objects. .groupBy() produces an array of subarrays containing the objects that pass the predicate that all objects must share the same d1d or grouping function. .reduce() boils all subarrays down to one value, your object with both ct s added to each other.

var merged = _.map(_.groupBy(a, 'd1d'), function(subGroup) {
  return subGroup.reduce(function(prev, curr) {
    return {
      d1d: prev.d1d,
      d1h: prev.d1h,
      d15m: prev.d15m,
      ct: prev.ct + curr.ct
    };
  });
});

Here's one possible solution:

var dataset = [{
 "d1d":"2015-05-28T00:00:00.000Z",
 "d1h":0,
 "d15m":0,
 "ct":3
},
{
 "d1d":"2015-05-28T00:00:00.000Z",
 "d1h":0,
 "d15m":0,
 "ct":1
}
]

function addCt(dataset) {
  var ctMap = {}
  var d1d, d1h, d15m, ct, key, value
  for (var ii=0, record; record=dataset[ii]; ii++) {
    key = record.d1d+"|"+record.d1h+"|"+record.d15m
    value = ctMap[key]
    if (!value) {
      value = 0
    }
    value += record.ct
    ctMap[key] = value
  }

  return ctMap
}

ctMap = addCt(dataset)
console.log(ctMap)
// { "2015-05-28T00:00:00.000Z|0|0": 4 }

You may want to construct the key in a different way. You may want set the value to an object containing the d1d, d1h, d15m and cumulated ct values, with a single object for all matching d1d, d1h and d15m values.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM