JavaScript/TypeScript: 统计数组中重复的对象,为每个项添加一个“amount”属性

huangapple go评论91阅读模式
英文:

JavaScript/TypeScript: count duplicate Objects in an Array of Objects to have an amount property on Item

问题

你可以尝试以下代码来实现你的目标:

  1. const items = [
  2. {
  3. "id": "fishing_rod",
  4. "emoji": "🎣",
  5. "description": "Used to go fishing.",
  6. "category": "fishing",
  7. },
  8. {
  9. "id": "fishing_rod",
  10. "emoji": "🎣",
  11. "description": "Used to go fishing.",
  12. "category": "fishing",
  13. },
  14. {
  15. "id": "pickaxe",
  16. "emoji": "⛏️",
  17. "description": "Used to go mining.",
  18. "category": "mining",
  19. },
  20. ];
  21. // 创建一个空的对象来存储每个项目的数量
  22. const itemCounts = {};
  23. // 遍历数组并计算每个项目的数量
  24. items.forEach(item => {
  25. const itemId = item.id;
  26. if (itemCounts[itemId]) {
  27. itemCounts[itemId]++;
  28. } else {
  29. itemCounts[itemId] = 1;
  30. }
  31. });
  32. // 将结果放入一个新的数组
  33. const result = Object.keys(itemCounts).map(itemId => ({
  34. ...items.find(item => item.id === itemId),
  35. amount: itemCounts[itemId]
  36. }));
  37. console.log(result);

这段代码会输出与你所期望的格式相匹配的结果。

英文:

So I have an array of items. There are duplicate items in that array and I am trying to count these duplicates. The count of those duplicates should be put into one of the duplicate items and the other item should be discarded.

My input:

(simplified)

  1. [
  2. {
  3. "id": "fishing_rod",
  4. "emoji": "🎣",
  5. "description": "Used to go fishing.",
  6. "category": "fishing",
  7. },
  8. {
  9. "id": "fishing_rod",
  10. "emoji": "🎣",
  11. "description": "Used to go fishing.",
  12. "category": "fishing",
  13. },
  14. {
  15. "id": "pickaxe",
  16. "emoji": "⛏️",
  17. "description": "Used to go mining.",
  18. "category": "mining",
  19. },
  20. ],

What I'm looking for:

  1. [
  2. {
  3. "id": "fishing_rod",
  4. "emoji": "🎣",
  5. "description": "Used to go fishing.",
  6. "category": "fishing",
  7. "amount": 2
  8. },
  9. {
  10. "id": "pickaxe",
  11. "emoji": "⛏️",
  12. "description": "Used to go mining.",
  13. "category": "mining",
  14. "amount": 1
  15. },
  16. ]

What I tried so far:

I have tried a few things but couldn't get there.

I've only gotten so far that I was able to only get the Item Id and the count. That looked a like this:

  1. const itemsArray = items.map((i) => i.id); // items being my input array (see top of this post)
  2. const itemsUnique = [...new Set(itemsArray)];
  3. const itemsCount = itemsUnique.map((item) => [item, itemsArray.filter((i) => i === item).length])

Output:

  1. [
  2. [ "fishing_rod", 2 ],
  3. [ "pickaxe", 1 ],
  4. ]

But that's not really what I am looking for...
A little help would be appreciated. <3

答案1

得分: 0

只需迭代并将具有相同id的项分组:

(以下代码段中有更简洁的版本。)

  1. function mergeItems(items) {
  2. const grouped = items.reduce((record, item) => {
  3. if (Object.hasOwn(record, item.id)) {
  4. record[item.id].count++;
  5. } else {
  6. record[item.id] = { ...item, count: 1 };
  7. }
  8. return record;
  9. }, {});
  10. return Object.values(grouped);
  11. }

尝试一下:

  1. console.config({ maximize: true });
  2. function mergeItems(items) {
  3. const grouped = items.reduce((record, item) => {
  4. record[item.id] ??= { ...item, count: 0 };
  5. record[item.id].count++;
  6. return record;
  7. }, {});
  8. return Object.values(grouped);
  9. }
  10. const input = [
  11. {
  12. "id": "fishing_rod",
  13. "emoji": "🎣",
  14. "description": "用于钓鱼。",
  15. "category": "钓鱼",
  16. },
  17. {
  18. "id": "fishing_rod",
  19. "emoji": "🎣",
  20. "description": "用于钓鱼。",
  21. "category": "钓鱼",
  22. },
  23. {
  24. "id": "pickaxe",
  25. "emoji": "⛏️",
  26. "description": "用于采矿。",
  27. "category": "采矿",
  28. },
  29. ];
  30. console.log(mergeItems(input));
  1. <script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

希望这有帮助。

英文:

Simply iterate over and group those with the same id:

(A terser version can be found in the snippet below.)

  1. function mergeItems(items) {
  2. const grouped = items.reduce((record, item) =&gt; {
  3. if (Object.hasOwn(record, item.id)) {
  4. record[item.id].count++;
  5. } else {
  6. record[item.id] = { ...item, count: 1 };
  7. }
  8. return record;
  9. }, {});
  10. return Object.values(grouped);
  11. }

Try it:

<!-- begin snippet: js hide: true console: false babel: false -->

<!-- language: lang-js -->

  1. console.config({ maximize: true });
  2. function mergeItems(items) {
  3. const grouped = items.reduce((record, item) =&gt; {
  4. record[item.id] ??= { ...item, count: 0 };
  5. record[item.id].count++;
  6. return record;
  7. }, {});
  8. return Object.values(grouped);
  9. }
  10. const input = [
  11. {
  12. &quot;id&quot;: &quot;fishing_rod&quot;,
  13. &quot;emoji&quot;: &quot;&#127907;&quot;,
  14. &quot;description&quot;: &quot;Used to go fishing.&quot;,
  15. &quot;category&quot;: &quot;fishing&quot;,
  16. },
  17. {
  18. &quot;id&quot;: &quot;fishing_rod&quot;,
  19. &quot;emoji&quot;: &quot;&#127907;&quot;,
  20. &quot;description&quot;: &quot;Used to go fishing.&quot;,
  21. &quot;category&quot;: &quot;fishing&quot;,
  22. },
  23. {
  24. &quot;id&quot;: &quot;pickaxe&quot;,
  25. &quot;emoji&quot;: &quot;⛏️&quot;,
  26. &quot;description&quot;: &quot;Used to go mining.&quot;,
  27. &quot;category&quot;: &quot;mining&quot;,
  28. },
  29. ];
  30. console.log(mergeItems(input));

<!-- language: lang-html -->

  1. &lt;script src=&quot;https://gh-canon.github.io/stack-snippet-console/console.min.js&quot;&gt;&lt;/script&gt;

<!-- end snippet -->

答案2

得分: 0

我们可以使用 filter 来移除重复项,同时增加计数。

  1. const input = [
  2. {"id": "fishing_rod", "emoji": "🎣", "description": "Used to go fishing.", "category": "fishing"},
  3. {"id": "fishing_rod", "emoji": "🎣", "description": "Used to go fishing.", "category": "fishing"},
  4. {"id": "pickaxe", "emoji": "⛏️", "description": "Used to go mining.", "category": "mining"}
  5. ]
  6. const output = input.filter((val, i, arr) => {
  7. const first = arr.findIndex(({ id }) => val.id === id);
  8. if (first === i)
  9. return val.amount = 1; // 当前值是第一次出现
  10. else arr[first].amount++; // 当前值不是第一次出现
  11. });
  12. console.log(output);

这是代码的翻译部分,没有其他内容。

英文:

We can use filter to remove the duplicates, at the same time incrementing the count.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

  1. const input = [{&quot;id&quot;: &quot;fishing_rod&quot;,&quot;emoji&quot;: &quot;&#127907;&quot;,&quot;description&quot;: &quot;Used to go fishing.&quot;,&quot;category&quot;: &quot;fishing&quot;,},{&quot;id&quot;: &quot;fishing_rod&quot;,&quot;emoji&quot;: &quot;&#127907;&quot;,&quot;description&quot;: &quot;Used to go fishing.&quot;,&quot;category&quot;: &quot;fishing&quot;,},{&quot;id&quot;: &quot;pickaxe&quot;,&quot;emoji&quot;: &quot;⛏️&quot;,&quot;description&quot;: &quot;Used to go mining.&quot;,&quot;category&quot;: &quot;mining&quot;,}]
  2. const output = input.filter((val, i, arr) =&gt; {
  3. const first = arr.findIndex(({ id }) =&gt; val.id === id)
  4. if(first === i)
  5. return val.amount = 1 // the current value is the first occurence
  6. else arr[first].amount++ // the current value is not the first occurence
  7. })
  8. console.log(output)

<!-- end snippet -->

答案3

得分: 0

  1. const source = [
  2. {
  3. "id": "fishing_rod",
  4. "emoji": "🎣",
  5. "description": "用于钓鱼。",
  6. "category": "钓鱼",
  7. },
  8. {
  9. "id": "fishing_rod",
  10. "emoji": "🎣",
  11. "description": "用于钓鱼。",
  12. "category": "钓鱼",
  13. },
  14. {
  15. "id": "pickaxe",
  16. "emoji": "⛏️",
  17. "description": "用于采矿。",
  18. "category": "采矿",
  19. },
  20. ];
  21. const result = {};
  22. source.forEach((item) => result[item.id] ? result[item.id].amount ++ : result[item.id] = { ...item, amount: 1});
  23. console.log(Object.values(result));

请注意,我已将表情符号和描述部分翻译成中文。

英文:

Technically a one-liner JavaScript/TypeScript: 统计数组中重复的对象,为每个项添加一个“amount”属性

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

  1. const source = [
  2. {
  3. &quot;id&quot;: &quot;fishing_rod&quot;,
  4. &quot;emoji&quot;: &quot;&#127907;&quot;,
  5. &quot;description&quot;: &quot;Used to go fishing.&quot;,
  6. &quot;category&quot;: &quot;fishing&quot;,
  7. },
  8. {
  9. &quot;id&quot;: &quot;fishing_rod&quot;,
  10. &quot;emoji&quot;: &quot;&#127907;&quot;,
  11. &quot;description&quot;: &quot;Used to go fishing.&quot;,
  12. &quot;category&quot;: &quot;fishing&quot;,
  13. },
  14. {
  15. &quot;id&quot;: &quot;pickaxe&quot;,
  16. &quot;emoji&quot;: &quot;⛏️&quot;,
  17. &quot;description&quot;: &quot;Used to go mining.&quot;,
  18. &quot;category&quot;: &quot;mining&quot;,
  19. },
  20. ];
  21. const result = {};
  22. source.forEach((item) =&gt; result[item.id] ? result[item.id].amount ++ : result[item.id] = { ...item, amount: 1});
  23. console.log(Object.values(result));

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年6月6日 08:09:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76410677.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定