如何基于每个对象内的两个条件聚合对象属性的数组

时间:2018-11-02 21:23:16

标签: javascript ecmascript-6

让我说我有这个对象数组:

[{
  a: "test", b: "5", c: 4
},
{
  a: "test 2", b: "2", c: 10
},
{
  a: "test", b: "5", c: 66
}]

我想聚合每个对象中属性ab相等的对象,所以我最终得到:

[{
   a: "test", b: "5", c: 70
},
{
   a: "test 2", b: "2", c: 10
}]

我可以在几个for循环中进行管理,例如

const a = [];
for(let item of data) {
    const dateTime  = new Date(item.T);
    const time = dateTime.getHours()+":"+dateTime.getMinutes()+":"+dateTime.getSeconds();
    const id = item.p+time+item.m;

    if (a[id]) {
        a[id].q = (parseFloat(a[id].q) + parseFloat(item.q)).toFixed(8)
    } else {
        a[id] = item;
    }
}
const b = [];
for (var key in a) { 
    b.push(a[key]); // converts to numbered array
}
return b;

...但是我想知道是否还有更好的方法?

2 个答案:

答案 0 :(得分:1)

更新

我认为这是优化的,因为您只循环了一次。我还尝试了尽可能多的优化。

const data = [
  { a: "test", b: "5", c: 4 },
  { a: "test 2", b: "2", c: 10 },
  { a: "test", b: "5", c: 66 }
]

function agregate(arr) {
  const result = [];
  const cache = {};
  const len = arr.length;

  for (let i = 0; i < len; ++i) {
    const item = arr[i];
    const itemC = item.c;
    const key = JSON.stringify({ a: item.a, b: item.b });

    // If is already cached, just agregates the c property.
    if (cache[key]) {
      cache[key][0] += itemC;
      result[cache[key][1]].c += itemC;
    } else {
      // Pushes into result and updates the cache {key} = [c value, index].
      result.push(item);
      cache[key] = [itemC, result.length - 1];
    }
  }

  return result;
}

console.time('Agregate');
console.log(agregate(data));
console.timeEnd('Agregate');

答案 1 :(得分:1)

使用var placeSearch, autocomplete; var componentForm = { street_number: 'short_name', route: 'long_name', locality: 'long_name', administrative_area_level_1: 'short_name', country: 'long_name', postal_code: 'short_name' }; function initAutocomplete() { autocomplete = new google.maps.places.Autocomplete( (document.getElementById('autocomplete')), { types: ['geocode'] }); autocomplete.addListener('place_changed', addlatlong); autocomplete2 = new google.maps.places.Autocomplete( document.getElementById('autocomplete2'), { types: [ 'geocode' ] }); autocomplete.addListener('place_changed', fillInAddress); } function addlatlong() { var place = autocomplete.getPlace(); var latitude = place.geometry.location.lat(); var longitude = place.geometry.location.lng(); document.getElementById("latitude").value = latitude; document.getElementById("longitude").value = longitude; } function fillInAddress() { // Get the place details from the autocomplete object. var place = autocomplete.getPlace(); for (var component in componentForm) { document.getElementById(component).value = ''; document.getElementById(component).disabled = false; } var latitude = place.geometry.location.lat(); var longitude = place.geometry.location.lng(); document.getElementById("latbox").value = latitude; document.getElementById("lngbox").value = longitude; console.log(`${latitude}`) console.log(`${longitude}`) // Get each component of the address from the place details // and fill the corresponding field on the form. for (var i = 0; i < place.address_components.length; i++) { var addressType = place.address_components[i].types[0]; if (componentForm[addressType]) { var val = place.address_components[i][componentForm[addressType]]; document.getElementById(addressType).value = val; } } } 可以使用一种更抽象的方法,但是我只是在这里挠头。

reduce