Поиск нескольких объектов в массиве и добавление для подсчета значения для этого объекта - PullRequest
0 голосов
/ 15 ноября 2018

Я пытался найти лучший способ сделать это и нашел несколько вариантов, но не тот, который сохраняет формат, который я пытаюсь сохранить для массива / объекта.

Обзор у меня естьмассив, в который вставляются случайные объекты, и могут быть дубликаты одного и того же объекта, но я хочу изменить его, чтобы в нем был только 1 для каждого объекта и вместо этого иметь свойство count для каждого объекта.

Пример того, с чем я работаю и к чему стремлюсь.

arr = [
  { Name: Item1, Value: 20 },
  { Name: Item2, Value: 20 },
  { Name: Item1, Value: 20 }
];

result = [
  { Name: Item1, Value: 20, Count: 2 },
  { Name: Item2, Value: 20, Count: 1 }
];

В качестве примечания, мне интересно, лучше ли это делать после заполнения массива или лучшесделать это, помещая объекты в массив?

Ответы [ 4 ]

0 голосов
/ 15 ноября 2018

Предполагая, что значение каждого элемента одинаково, вы можете сделать простой цикл forEach.Для каждого элемента проверьте, существует ли объект в «результате».Если это так, увеличьте счетчик, иначе добавьте его в массив результатов.

let result = [];

arr.forEach(item => {
  let resObj = result.find(resObj => resObj.Name === item.Name);
  resObj ? resObj.Count++ : result.push({'Name':item.Name, 'Value': item.Value, 'Count': 1});
});

console.log(result);

В этом случае вы не хотите использовать arr.map, поскольку мы не обновляем исходный массив.

0 голосов
/ 15 ноября 2018

Вы можете взять хеш-таблицу и сосчитать те же элементы.

var array = [{ Name: 'Item1', Value: 20 }, { Name: 'Item2', Value: 20 }, { Name: 'Item1', Value: 20 }],
    result = Object.values(array.reduce((r, { Name, Value }) => {
        r[Name] = r[Name] || { Name, Value, Count: 0 };
        r[Name].Count++;
        return r;
    }, {}));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 15 ноября 2018

Вы можете циклически перемещаться по массиву и поддерживать 1 временный объект с «Именем» в качестве ключа. Если найдено то же имя, увеличьте «количество» на 1

let array = [{ Name: 'Item1', Value: 20 }, { Name: 'Item2', Value: 20 }, { Name: 'Item1', Value: 20 }]
    
let tempResult = {}
for (let d of array) {
  tempResult[d.Name] = { 
     count: 1, 
     ...d, 
     ...(tempResult[d.Name] &&  { count: tempResult[d.Name].count + 1 }) 
  }
}

let result = Object.values(tempResult)
console.log(result);
0 голосов
/ 15 ноября 2018

Если элементы постоянно добавляются, вы можете поддерживать «индекс» (на Name) объектов, которые вы уже добавили в массив, чтобы при каждом добавлении нового объекта вы могли обновлять счетчик, если он уже представить или передать его в массив, если это не так:

var arr = [];
var index = {};

function addItem(o) {
  if (o.Name in index) {
    index[o.Name].Count += 1;
  } else {
    index[o.Name] = o;
    o.Count = 1;
    arr.push(o);
  }
}

addItem({
  Name: 'Item1',
  Value: 20
});
addItem({
  Name: 'Item2',
  Value: 20
});
addItem({
  Name: 'Item1',
  Value: 20
});

console.log(arr);

Преимущество этого подхода заключается в том, что вам не нужно пересчитывать счет с нуля (что является O (n) операцией) каждый раз, когда вы хотите получить массив result.

...