Как найти несколько вхождений в массиве объектов и добавить значение счетчика? - PullRequest
4 голосов
/ 12 мая 2019

В настоящее время я пытаюсь подсчитать несколько вхождений в массиве объектов и добавить окончательный подсчет в него. Я не хочу хранить данные в дополнительном массиве. Данные должны остаться в существующей.

Массив, который я бы попытался добавить в счет

var array = [
    { artist: 'metallica', venue: 'olympiastadion' },
    { artist: 'foofighters', venue: 'wuhlheide' },
    { artist: 'metallica', venue: 'columbiahalle' },
    { artist: 'deftones', venue: 'columbiahalle' },
    { artist: 'deichkind', venue: 'wuhlheide' },
    { artist: 'metallica', venue: 'wuhlheide' },
    { artist: 'foofighters', venue: 'trabrennbahn' }
];

Мой текущий пример кода удаляет / уменьшает из массива, поэтому конечный результат не такой, как хотелось бы:

var array = [
    { artist: 'metallica', venue: 'olympiastadion' },
    { artist: 'foofighters', venue: 'wuhlheide' },
    { artist: 'metallica', venue: 'columbiahalle' },
    { artist: 'deftones', venue: 'columbiahalle' },
    { artist: 'deichkind', venue: 'wuhlheide' },
    { artist: 'metallica', venue: 'wuhlheide' },
    { artist: 'foofighters', venue: 'trabrennbahn' }
];

array = Object.values(array.reduce((r, { artist, venue }) => {
    r[artist] = r[artist] || { artist, venue, count: 0 };
    r[artist].count++;
    return r;
}, {}));

console.log(array);

Which logs:
    { artist: 'metallica', venue: 'olympiastadion', count: 3 },
    { artist: 'foofighters', venue: 'wuhlheide', count: 2 },
    { artist: 'deftones', venue: 'columbiahalle', count: 1 },
    { artist: 'deichkind', venue: 'wuhlheide', count: 1 }

Я пытаюсь добиться результата как:

var array = [
    { artist: 'metallica', venue: 'olympiastadion', count: 3 },
    { artist: 'foofighters', venue: 'wuhlheide', count: 2 },
    { artist: 'metallica', venue: 'columbiahalle', count: 3 },
    { artist: 'deftones', venue: 'columbiahalle', count: 1 },
    { artist: 'deichkind', venue: 'wuhlheide', count: 1 },
    { artist: 'metallica', venue: 'wuhlheide', count: 3 },
    { artist: 'foofighters', venue: 'trabrennbahn', count: 2 }
];

Любая помощь приветствуется, чтобы указать мне правильное направление.

Спасибо за помощь! Желаемое решение:

var array = [{ artist: 'metallica', venue: 'olympiastadion' }, { artist: 'foofighters', venue: 'wuhlheide' }, { artist: 'metallica', venue: 'columbiahalle' }, { artist: 'deftones', venue: 'columbiahalle' }, { artist: 'deichkind', venue: 'wuhlheide' }, { artist: 'metallica', venue: 'wuhlheide' }, { artist: 'foofighters', venue: 'trabrennbahn' }],
    map = array.reduce( 
        (map, { artist }) => map.set(artist, (map.get(artist) || 0) + 1),
        new Map
    ),
    array = array.map(o => Object.assign({}, o, { count: map.get(o.artist) }));

console.log(array);

Ответы [ 4 ]

6 голосов
/ 12 мая 2019

Вы можете сначала получить счет, перебрав все элементы, а затем присвоив новому объекту старый объект и новое свойство счетчика.

var array = [{ artist: 'metallica', venue: 'olympiastadion' }, { artist: 'foofighters', venue: 'wuhlheide' }, { artist: 'metallica', venue: 'columbiahalle' }, { artist: 'deftones', venue: 'columbiahalle' }, { artist: 'deichkind', venue: 'wuhlheide' }, { artist: 'metallica', venue: 'wuhlheide' }, { artist: 'foofighters', venue: 'trabrennbahn' }],
    map = array.reduce( 
        (map, { artist }) => map.set(artist, (map.get(artist) || 0) + 1),
        new Map
    ),
    result = array.map(o => Object.assign({}, o, { count: map.get(o.artist) }));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
2 голосов
/ 12 мая 2019

Вы можете сделать это в следующих шагах:

  • Создать объект из массива, используя reduce(), который имеет количество всех уникальных художников
  • У объекта будут ключи, которые будутразличные artists и их значения будут их количеством.
  • Затем используйте forEach в исходном массиве.
  • Установите count всех значений художника текущего элементав массиве подсчетов.

var array = [
    { artist: 'metallica', venue: 'olympiastadion' },
    { artist: 'foofighters', venue: 'wuhlheide' },
    { artist: 'metallica', venue: 'columbiahalle' },
    { artist: 'deftones', venue: 'columbiahalle' },
    { artist: 'deichkind', venue: 'wuhlheide' },
    { artist: 'metallica', venue: 'wuhlheide' },
    { artist: 'foofighters', venue: 'trabrennbahn' }
];

const unique = array.reduce((ac,{artist:a}) => (ac[a] = ac[a] + 1 || 1,ac),{});
array.forEach(x => x.count = unique[x.artist]);
console.log(array)
1 голос
/ 12 мая 2019

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

var array = [
    { artist: 'metallica', venue: 'olympiastadion' },
    { artist: 'foofighters', venue: 'wuhlheide' },
    { artist: 'metallica', venue: 'columbiahalle' },
    { artist: 'deftones', venue: 'columbiahalle' },
    { artist: 'deichkind', venue: 'wuhlheide' },
    { artist: 'metallica', venue: 'wuhlheide' },
    { artist: 'foofighters', venue: 'trabrennbahn' }
];

var counts = array.reduce((counts, item) => {
  var artistName = item.artist;
  if (counts[artistName]) {
    counts[artistName] += 1;
  } else {
    counts[artistName] = 1;
  }
  
  return counts;
}, {});

array.forEach(item => item.count = counts[item.artist])

console.log(array);

Функция .reduce многословна для ясности, но ее можно значительно сократить:

var array = [
    { artist: 'metallica', venue: 'olympiastadion' },
    { artist: 'foofighters', venue: 'wuhlheide' },
    { artist: 'metallica', venue: 'columbiahalle' },
    { artist: 'deftones', venue: 'columbiahalle' },
    { artist: 'deichkind', venue: 'wuhlheide' },
    { artist: 'metallica', venue: 'wuhlheide' },
    { artist: 'foofighters', venue: 'trabrennbahn' }
];

var counts = array.reduce((counts, item) => (counts[item.artist] = counts[item.artist] || 1, counts), {});

console.log(counts);

Если вы хотите создать новый массив вместо изменения объектов в старом, то вы можете сделать копию каждого объекта имассив:

var array = [
    { artist: 'metallica', venue: 'olympiastadion' },
    { artist: 'foofighters', venue: 'wuhlheide' },
    { artist: 'metallica', venue: 'columbiahalle' },
    { artist: 'deftones', venue: 'columbiahalle' },
    { artist: 'deichkind', venue: 'wuhlheide' },
    { artist: 'metallica', venue: 'wuhlheide' },
    { artist: 'foofighters', venue: 'trabrennbahn' }
];

var counts = {
  "metallica": 3,
  "foofighters": 2,
  "deftones": 1,
  "deichkind": 1
}

var newArray = array.map(item => ({...item, count: counts[item.artist]}))

console.log(newArray);
console.log(array);
0 голосов
/ 12 мая 2019

Вы можете выполнить итерацию дважды по массиву.

var array = [
    { artist: 'metallica', venue: 'olympiastadion' },
    { artist: 'foofighters', venue: 'wuhlheide' },
    { artist: 'metallica', venue: 'columbiahalle' },
    { artist: 'deftones', venue: 'columbiahalle' },
    { artist: 'deichkind', venue: 'wuhlheide' },
    { artist: 'metallica', venue: 'wuhlheide' },
    { artist: 'foofighters', venue: 'trabrennbahn' }
];

array.forEach(a => {
  if (!a.hasOwnProperty('count')) {
    Object.assign(a, { count: 0 });
  }
  array.forEach(b => {
    if (a.artist === b.artist) {
      a.count++;
    }
  });
});

console.log(array);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...