admin管理员组

文章数量:1397134

Currently I am trying to count multiple occurrences inside an array of objects and push a final counting into it. I do not want to have the data storred in an additional array. The data should stay in the existing one.

The array I'd try to add the 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' }
];

My current example code deletes/reduces from the array so the final result is not as desired:

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 }

I am trying to achieve the result as:

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 }
];

Any help is appreciated to point me in the right direction.

Thank you for helping! The desired solution is:

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);

Currently I am trying to count multiple occurrences inside an array of objects and push a final counting into it. I do not want to have the data storred in an additional array. The data should stay in the existing one.

The array I'd try to add the 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' }
];

My current example code deletes/reduces from the array so the final result is not as desired:

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 }

I am trying to achieve the result as:

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 }
];

Any help is appreciated to point me in the right direction.

Thank you for helping! The desired solution is:

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);
Share Improve this question edited May 12, 2019 at 20:06 Emma 27.8k11 gold badges48 silver badges71 bronze badges asked May 12, 2019 at 18:16 huppenhuppen 511 silver badge6 bronze badges 3
  • { artist: 'metallica', venue: 'olympiastadion', count: 3 } doesn't really make sense. – Andy Commented May 12, 2019 at 18:25
  • do you want the same array object with an update, or a new array with independent new objects? – Nina Scholz Commented May 12, 2019 at 18:26
  • @Andy it might does not make sense in this tiny context here. – huppen Commented May 12, 2019 at 18:45
Add a ment  | 

4 Answers 4

Reset to default 5

You could get the count first by iterating over all items and then assign to a new object the old object and a new count property.

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; }

You can do that in following steps:

  • Create an object from array using reduce() which have count of all the unique artists
  • The object will have keys which will different artists and their values will be their count.
  • Then use forEach on the original array.
  • Set the count of all the to the value of artist of current item in count array.

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)

You can do one pass over the array building a map of artist name to a count, and a second pass to modify each array item adding the count associated with the artist.

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);

The .reduce function is verbose for clarity but it can be shortened a lot:

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);

If you want to create a new array instead of modifying the objects in the old one, then you can make a copy of each object and the array:

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);

You can iterate two times over the array.

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);

本文标签: javascriptHow to find multiple occurrences in an array of objects and add count valueStack Overflow