javascriptarraysfiltersumcombiners

Javascript Array combine elements to get a unique array


Suppose I have a JS array like this:

[
  {
    "lat": 49.26125,
    "lon": -123.24807,
    "weight": 120
  },
  {
    "lat": 49.26125,
    "lon": -123.24807,
    "weight": 80
  },
  {
    "lat": 49.26125,
    "lon": -123.24807,
    "weight": 160
  },
  {
    "lat": 49.26229,
    "lon": 23.24342,
    "weight": 236
  },
  {
    "lat": 49.26229,
    "lon": 23.24342,
    "weight": 167
  }
]

Suppose I want to add up the weights the elements that have the same lat & lon to get something like this:

[
  {
    "lat": 49.26125,
    "lon": -123.24807,
    "weight": 360
  },
  {
    "lat": 49.26229,
    "lon": 23.24342,
    "weight": 403
  }
]

what's an efficient way to do that in JS?


Solution

  • You can do this by reduce-ing your array to form a map from unique [lat, lon] pairs to a merged object that accumulates your total weight. Your result is then the list of values held by that map (which can be obtained using Object.keys and Array#map).

    var array = [{lat:49.26125,lon:-123.24807,weight:120},{lat:49.26125,lon:-123.24807,weight:80},{lat:49.26125,lon:-123.24807,weight:160},{lat:49.26229,lon:23.24342,weight:236},{lat:49.26229,lon:23.24342,weight:167}]
    
    var map = array.reduce(function (map, o) {
      var k = [o.lat, o.lon].join()
      
      if (k in map)
        map[k].weight += o.weight
      else 
        map[k] = o
      
      return map
    }, {})
    
    var result = Object.keys(map).map(function (k) { return map[k] })
    
    console.log(result)
    .as-console-wrapper { min-height: 100%; }