问题
Currently have an array of objects which contain game releases. However game releases can happen on multiple platforms and these appear as separate objects within the array. I'm looking to remove duplicate games by comparing the game id but merge the platforms object
I have tried using the reduce function which successfully removes duplicate objects by game id but I'm unable to adapt this to merge platforms
const filteredArr = data.reduce((acc, current) => {
const x = acc.find(item => item.game.id === current.game.id);
if (!x) {
return acc.concat([current]);
} else {
return acc;
}
}, []);
Current Array:
const data = [{
"id": 157283,
"date": 1553212800,
"game": {
"id": 76882,
"name": "Sekiro: Shadows Die Twice",
"popularity": 41.39190295640344
},
"human": "2019-Mar-22",
"m": 3,
"platform": {"id": 48, "name": "PlayStation 4"},
"region": 8,
"y": 2019
}, {
"id": 12,
"date": 1553212800,
"game": {
"id": 76832,
"name": "Spiderman",
"popularity": 41.39190295640344
},
"human": "2019-Mar-22",
"m": 3,
"platform": {"id": 6, "name": "PC (Microsoft Windows)"},
"region": 8,
"y": 2019
}, {
"id": 157283,
"date": 1553212800,
"game": {
"id": 76882,
"name": "Sekiro: Shadows Die Twice",
"popularity": 41.39190295640344
},
"human": "2019-Mar-22",
"m": 3,
"platform": {"id": 48, "name": "Xbox"},
"region": 8,
"y": 2019
}]
Expected format after merge:
[{
"id": 157283,
"date": 1553212800,
"game": {
"id": 76882,
"name": "Sekiro: Shadows Die Twice",
"popularity": 41.39190295640344
},
"human": "2019-Mar-22",
"m": 3,
"platforms": ["PlayStation", "Xbox"],
"region": 8,
"y": 2019
}, {
"id": 12,
"date": 1553212800,
"game": {
"id": 76832,
"name": "Spiderman",
"popularity": 41.39190295640344
},
"human": "2019-Mar-22",
"m": 3,
"platforms": ["Playstation"],
"region": 8,
"y": 2019
}]
回答1:
You were really close, you just need to change the logic a bit. You can try something like the following; an example - https://repl.it/@EQuimper/ScaryBumpyCircle
const filteredArr = data.reduce((acc, current) => {
const x = acc.find(item => item.game.id === current.game.id);
if (!x) {
current.platform = [current.platform]
acc.push(current);
} else {
x.platform.push(current.platform);
}
return acc;
}, []);
The return value is
[
{
"id": 157283,
"date": 1553212800,
"game": {
"id": 76882,
"name": "Sekiro: Shadows Die Twice",
"popularity": 41.39190295640344
},
"human": "2019-Mar-22",
"m": 3,
"platform": [
{
"id": 48,
"name": "PlayStation 4"
},
{
"id": 48,
"name": "Xbox"
}
],
"region": 8,
"y": 2019
},
{
"id": 12,
"date": 1553212800,
"game": {
"id": 76832,
"name": "Spiderman",
"popularity": 41.39190295640344
},
"human": "2019-Mar-22",
"m": 3,
"platform": [
{
"id": 6,
"name": "PC (Microsoft Windows)"
}
],
"region": 8,
"y": 2019
}
]
If you want to have just an array of platform strings, go with
const filteredArr = data.reduce((acc, current) => {
const x = acc.find(item => item.game.id === current.game.id);
if (!x) {
current.platform = [current.platform.name]
acc.push(current);
} else {
x.platform.push(current.platform.name);
}
return acc;
}, []);
And now the return value is
[
{
"id": 157283,
"date": 1553212800,
"game": {
"id": 76882,
"name": "Sekiro: Shadows Die Twice",
"popularity": 41.39190295640344
},
"human": "2019-Mar-22",
"m": 3,
"platform": [
"PlayStation 4",
"Xbox"
],
"region": 8,
"y": 2019
},
{
"id": 12,
"date": 1553212800,
"game": {
"id": 76832,
"name": "Spiderman",
"popularity": 41.39190295640344
},
"human": "2019-Mar-22",
"m": 3,
"platform": [
"PC (Microsoft Windows)"
],
"region": 8,
"y": 2019
}
]
回答2:
You could separate platform
of the object and look if you have an object with the same id
and add the platfor tho the array, of not create a new data set.
const
data = [{ id: 157283, date: 1553212800, game: { id: 76882, name: "Sekiro: Shadows Die Twice", popularity: 41.39190295640344 }, human: "2019-Mar-22", m: 3, platform: { id: 48, name: "PlayStation 4" }, region: 8, y: 2019 }, { id: 12, date: 1553212800, game: { id: 76832, name: "Spiderman", popularity: 41.39190295640344 }, human: "2019-Mar-22", m: 3, platform: { id: 6, name: "PC (Microsoft Windows)" }, region: 8, y: 2019 }, { id: 157283, date: 1553212800, game: { id: 76882, name: "Sekiro: Shadows Die Twice", popularity: 41.39190295640344 }, human: "2019-Mar-22", m: 3, platform: { id: 48, name: "Xbox" }, region: 8, y: 2019 }],
result = data.reduce((r, { platform, ...o }) => {
var temp = r.find(({ id }) => id === o.id);
if (!temp) r.push(temp = { ...o, platforms: [] });
temp.platforms.push(platform);
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
回答3:
Please take a look:
const data = [ { "id": 157283,
"date": 1553212800,
"game": {
"id": 76882,
"name": "Sekiro: Shadows Die Twice",
"popularity": 41.39190295640344
},
"human": "2019-Mar-22",
"m": 3,
"platform": {
"id": 48,
"name": "PlayStation 4"
},
"region": 8,
"y": 2019
},
{
"id": 12,
"date": 1553212800,
"game": {
"id": 76832,
"name": "Spiderman",
"popularity": 41.39190295640344
},
"human": "2019-Mar-22",
"m": 3,
"platform": {
"id": 6,
"name": "PC (Microsoft Windows)"
},
"region": 8,
"y": 2019
},{ "id": 157283,
"date": 1553212800,
"game": {
"id": 76882,
"name": "Sekiro: Shadows Die Twice",
"popularity": 41.39190295640344
},
"human": "2019-Mar-22",
"m": 3,
"platform": {
"id": 48,
"name": "Xbox"
},
"region": 8,
"y": 2019
},
]
const filteredArr = data.reduce((acc, current) => {
const x = acc.find(item => item.game.id === current.game.id);
if (!x) {
current.platform = [current.platform.name]
return acc.concat([current]);
} else {
x.platform.push(current.platform.name);
return acc;
}
}, []);
console.log(filteredArr);
回答4:
Here is another solution, using forEach
instead of reduce
. This makes use of a lookup hash that makes if faster for larger amounts of data then using find
.
const data = [{"id": 157283, "date": 1553212800, "game": {"id": 76882, "name": "Sekiro: Shadows Die Twice", "popularity": 41.39190295640344}, "human": "2019-Mar-22", "m": 3, "platform": {"id": 48, "name": "PlayStation 4"}, "region": 8, "y": 2019}, {"id": 12, "date": 1553212800, "game": {"id": 76832, "name": "Spiderman", "popularity": 41.39190295640344}, "human": "2019-Mar-22", "m": 3, "platform": {"id": 6, "name": "PC (Microsoft Windows)"}, "region": 8, "y": 2019}, {"id": 157283, "date": 1553212800, "game": {"id": 76882, "name": "Sekiro: Shadows Die Twice", "popularity": 41.39190295640344}, "human": "2019-Mar-22", "m": 3, "platform": {"id": 48, "name": "Xbox"}, "region": 8, "y": 2019}];
let result = {};
data.forEach(({platform, ...release}) => {
release.platforms = [platform.name];
const releaseLookup = result[release.game.id];
if (!releaseLookup) {
result[release.game.id] = release;
} else {
releaseLookup.platforms.push(...release.platforms);
}
});
console.log(Object.values(result));
来源:https://stackoverflow.com/questions/56890433/remove-duplicate-objects-from-an-array-but-merge-nested-objects