I have two JS related objects with IDs. I need to filter the first object based on second object value color
. The filter function works for me but I get an array, I need an object.
The objects are similar like this:
"matchs": {
"123": {
id: "123",
array_players: [ "1","2" ],
},
"345": {
id: "345",
array_players: [ "1","4" ],
},
"611": {
id: "611",
array_players: [ "2","5" ],
}
};
"players": {
"1": { "id": "1", "name": "Mike", color: "green"},
"2": { "id": "2", "name": "Andy", color: "yellow" },
"3": { "id": "3", "name": "Tony", color: "blue"},
"4": { "id": "4", "name": "Joe", color: "green" }
"5": { "id": "4", "name": "Lisa", color: "red" }
}
The ES6 filter function:
var filter = Object.values(matchs).filter(function(match){
return (
match.array_players.find (function(player_id){
return (players[player_id].color === 'green')
})
);
});
But the result is an array not object like original matchs
:
[
0: {
id: "123",
array_players: [ "1","2" ],
},
1: {
id: "345",
array_players: [ "1","4" ],
}
];
I'll need something like this:
"matchs": {
"123": {
id: "123",
array_players: [ "1","2" ],
},
"345": {
id: "345",
array_players: [ "1","4" ],
},
};
I have two JS related objects with IDs. I need to filter the first object based on second object value color
. The filter function works for me but I get an array, I need an object.
The objects are similar like this:
"matchs": {
"123": {
id: "123",
array_players: [ "1","2" ],
},
"345": {
id: "345",
array_players: [ "1","4" ],
},
"611": {
id: "611",
array_players: [ "2","5" ],
}
};
"players": {
"1": { "id": "1", "name": "Mike", color: "green"},
"2": { "id": "2", "name": "Andy", color: "yellow" },
"3": { "id": "3", "name": "Tony", color: "blue"},
"4": { "id": "4", "name": "Joe", color: "green" }
"5": { "id": "4", "name": "Lisa", color: "red" }
}
The ES6 filter function:
var filter = Object.values(matchs).filter(function(match){
return (
match.array_players.find (function(player_id){
return (players[player_id].color === 'green')
})
);
});
But the result is an array not object like original matchs
:
[
0: {
id: "123",
array_players: [ "1","2" ],
},
1: {
id: "345",
array_players: [ "1","4" ],
}
];
I'll need something like this:
"matchs": {
"123": {
id: "123",
array_players: [ "1","2" ],
},
"345": {
id: "345",
array_players: [ "1","4" ],
},
};
Share
Improve this question
asked Jan 11, 2018 at 18:03
kurtkokurtko
2,1364 gold badges33 silver badges49 bronze badges
1
- Try lodash or underscore with find - returns the 1st object that matches – Phil Boyd Commented Jan 11, 2018 at 18:05
4 Answers
Reset to default 4You could map the objects and use Object.assign
for getting all objects into a single object.
var matchs = { 123: { id: "123", array_players: ["1", "2"] }, 345: { id: "345", array_players: ["1", "4"] }, 611: { id: "611", array_players: ["2", "5"] } },
players = { 1: { id: "1", name: "Mike", color: "green" }, 2: { id: "2", name: "Andy", color: "yellow" }, 3: { id: "3", name: "Tony", color: "blue" }, 4: { id: "4", name: "Joe", color: "green" }, 5: { id: "4", name: "Lisa", color: "red" } },
result = Object.assign(
{},
...Object
.keys(matchs)
.filter(k => matchs[k].array_players.some(l => players[l].color === 'green'))
.map(k => ({ [k]: matchs[k] }))
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can add another step of Array#reduce
to fold the array of matches down to an object.
I would also avoid using Object.values
as it is only patible with modern browsers and would require a shim. You can use Object.keys
to do the same but with more patibility.
const matches = {
"123": {
id: "123",
array_players: [ "1","2" ],
},
"345": {
id: "345",
array_players: [ "1","4" ],
},
"611": {
id: "611",
array_players: [ "2","5" ],
}
};
const players = {
"1": { "id": "1", "name": "Mike", color: "green"},
"2": { "id": "2", "name": "Andy", color: "yellow" },
"3": { "id": "3", "name": "Tony", color: "blue"},
"4": { "id": "4", "name": "Joe", color: "green" },
"5": { "id": "4", "name": "Lisa", color: "red" }
}
const filterByPlayerColor = (color, players) =>
Object.keys(matches).filter(x =>
matches[x].array_players.find(id => players[id].color === color)
)
.reduce((acc, x) => ({ ...acc, [x]: matches[x] }), {})
console.log(
filterByPlayerColor('green', players)
)
<script src="https://codepen.io/synthet1c/pen/KyQQmL.js"></script>
const result = {};
for(const {id, array_players} of Object.values(matchs))
result[id] = {id, array_players: array_players.filter(playerID => players[playerID].color === "green")};
You need to set up a new object and set its properties.
try to use a reducer and build the resultant object. try this one,
let _iterator = (val) => {
return players[val].color === 'green'
}
let _reducer = (acc, currVal, currIndex, arr) => {
let res = matchs[arr[currIndex]].array_players.some(_iterator);
res && (acc[arr[currIndex]] = matchs[arr[currIndex]]);
return acc;
}
let result = {matchs: Object.keys(matchs).reduce(_reducer, {})};
console.log(result)