英文:
JavaScript/TypeScript: count duplicate Objects in an Array of Objects to have an amount property on Item
问题
你可以尝试以下代码来实现你的目标:
const items = [
{
"id": "fishing_rod",
"emoji": "🎣",
"description": "Used to go fishing.",
"category": "fishing",
},
{
"id": "fishing_rod",
"emoji": "🎣",
"description": "Used to go fishing.",
"category": "fishing",
},
{
"id": "pickaxe",
"emoji": "⛏️",
"description": "Used to go mining.",
"category": "mining",
},
];
// 创建一个空的对象来存储每个项目的数量
const itemCounts = {};
// 遍历数组并计算每个项目的数量
items.forEach(item => {
const itemId = item.id;
if (itemCounts[itemId]) {
itemCounts[itemId]++;
} else {
itemCounts[itemId] = 1;
}
});
// 将结果放入一个新的数组
const result = Object.keys(itemCounts).map(itemId => ({
...items.find(item => item.id === itemId),
amount: itemCounts[itemId]
}));
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)
[
{
"id": "fishing_rod",
"emoji": "🎣",
"description": "Used to go fishing.",
"category": "fishing",
},
{
"id": "fishing_rod",
"emoji": "🎣",
"description": "Used to go fishing.",
"category": "fishing",
},
{
"id": "pickaxe",
"emoji": "⛏️",
"description": "Used to go mining.",
"category": "mining",
},
],
What I'm looking for:
[
{
"id": "fishing_rod",
"emoji": "🎣",
"description": "Used to go fishing.",
"category": "fishing",
"amount": 2
},
{
"id": "pickaxe",
"emoji": "⛏️",
"description": "Used to go mining.",
"category": "mining",
"amount": 1
},
]
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:
const itemsArray = items.map((i) => i.id); // items being my input array (see top of this post)
const itemsUnique = [...new Set(itemsArray)];
const itemsCount = itemsUnique.map((item) => [item, itemsArray.filter((i) => i === item).length])
Output:
[
[ "fishing_rod", 2 ],
[ "pickaxe", 1 ],
]
But that's not really what I am looking for...
A little help would be appreciated. <3
答案1
得分: 0
只需迭代并将具有相同id
的项分组:
(以下代码段中有更简洁的版本。)
function mergeItems(items) {
const grouped = items.reduce((record, item) => {
if (Object.hasOwn(record, item.id)) {
record[item.id].count++;
} else {
record[item.id] = { ...item, count: 1 };
}
return record;
}, {});
return Object.values(grouped);
}
尝试一下:
console.config({ maximize: true });
function mergeItems(items) {
const grouped = items.reduce((record, item) => {
record[item.id] ??= { ...item, count: 0 };
record[item.id].count++;
return record;
}, {});
return Object.values(grouped);
}
const input = [
{
"id": "fishing_rod",
"emoji": "🎣",
"description": "用于钓鱼。",
"category": "钓鱼",
},
{
"id": "fishing_rod",
"emoji": "🎣",
"description": "用于钓鱼。",
"category": "钓鱼",
},
{
"id": "pickaxe",
"emoji": "⛏️",
"description": "用于采矿。",
"category": "采矿",
},
];
console.log(mergeItems(input));
<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.)
function mergeItems(items) {
const grouped = items.reduce((record, item) => {
if (Object.hasOwn(record, item.id)) {
record[item.id].count++;
} else {
record[item.id] = { ...item, count: 1 };
}
return record;
}, {});
return Object.values(grouped);
}
Try it:
<!-- begin snippet: js hide: true console: false babel: false -->
<!-- language: lang-js -->
console.config({ maximize: true });
function mergeItems(items) {
const grouped = items.reduce((record, item) => {
record[item.id] ??= { ...item, count: 0 };
record[item.id].count++;
return record;
}, {});
return Object.values(grouped);
}
const input = [
{
"id": "fishing_rod",
"emoji": "🎣",
"description": "Used to go fishing.",
"category": "fishing",
},
{
"id": "fishing_rod",
"emoji": "🎣",
"description": "Used to go fishing.",
"category": "fishing",
},
{
"id": "pickaxe",
"emoji": "⛏️",
"description": "Used to go mining.",
"category": "mining",
},
];
console.log(mergeItems(input));
<!-- language: lang-html -->
<script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
<!-- end snippet -->
答案2
得分: 0
我们可以使用 filter
来移除重复项,同时增加计数。
const input = [
{"id": "fishing_rod", "emoji": "🎣", "description": "Used to go fishing.", "category": "fishing"},
{"id": "fishing_rod", "emoji": "🎣", "description": "Used to go fishing.", "category": "fishing"},
{"id": "pickaxe", "emoji": "⛏️", "description": "Used to go mining.", "category": "mining"}
]
const output = input.filter((val, i, arr) => {
const first = arr.findIndex(({ id }) => val.id === id);
if (first === i)
return val.amount = 1; // 当前值是第一次出现
else arr[first].amount++; // 当前值不是第一次出现
});
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 -->
const input = [{"id": "fishing_rod","emoji": "🎣","description": "Used to go fishing.","category": "fishing",},{"id": "fishing_rod","emoji": "🎣","description": "Used to go fishing.","category": "fishing",},{"id": "pickaxe","emoji": "⛏️","description": "Used to go mining.","category": "mining",}]
const output = input.filter((val, i, arr) => {
const first = arr.findIndex(({ id }) => val.id === id)
if(first === i)
return val.amount = 1 // the current value is the first occurence
else arr[first].amount++ // the current value is not the first occurence
})
console.log(output)
<!-- end snippet -->
答案3
得分: 0
const source = [
{
"id": "fishing_rod",
"emoji": "🎣",
"description": "用于钓鱼。",
"category": "钓鱼",
},
{
"id": "fishing_rod",
"emoji": "🎣",
"description": "用于钓鱼。",
"category": "钓鱼",
},
{
"id": "pickaxe",
"emoji": "⛏️",
"description": "用于采矿。",
"category": "采矿",
},
];
const result = {};
source.forEach((item) => result[item.id] ? result[item.id].amount ++ : result[item.id] = { ...item, amount: 1});
console.log(Object.values(result));
请注意,我已将表情符号和描述部分翻译成中文。
英文:
Technically a one-liner
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const source = [
{
"id": "fishing_rod",
"emoji": "🎣",
"description": "Used to go fishing.",
"category": "fishing",
},
{
"id": "fishing_rod",
"emoji": "🎣",
"description": "Used to go fishing.",
"category": "fishing",
},
{
"id": "pickaxe",
"emoji": "⛏️",
"description": "Used to go mining.",
"category": "mining",
},
];
const result = {};
source.forEach((item) => result[item.id] ? result[item.id].amount ++ : result[item.id] = { ...item, amount: 1});
console.log(Object.values(result));
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论