Reputation: 39
i have an object like this (this is how we see the object in chrome dev tools for example):
obj: {
1: {...},
2: {...},
3: {...},
4: {...},
5: {...},
}
And i have a simple array like this:
arr: [1,3,5,7]
Basically i want my object to stay just with the keys that are in the array, like this:
obj: {
1: {...},
3: {...},
5: {...},
}
At the moment my code is this:
var select = (arr, obj) => arr.reduce((r, e) =>
Object.assign(r, obj[e] ? { [e]: obj[e] } : null)
, {});
var output = select(arr, obj);
I dont know why but this sometimes works and other times don´t. I can not use Jquery. Can anyone help me?
Upvotes: 0
Views: 203
Reputation: 21161
You could use Object.fromEntries()
, Object.entries()
, Array.prototype.filter()
and Array.prototype.includes()
to filter out the keys that are not inside arr
:
const obj ={
1: {},
2: {},
3: {},
4: {},
5: {},
};
const arr = [1, 3, 5, 7];
const filtered = Object.fromEntries(
// Note `key` is an `string` here, thus the `+`:
Object.entries(obj).filter(([key]) => arr.includes(+key))
);
console.log(filtered);
Or a simple for
loop, for...of
in this case, again with Array.prototype.includes()
to pick the ones you want (rather than filtering those you don't) and Object.prototype.hasOwnProperty()
to avoid adding keys that don't exist in obj
:
const obj ={
1: {},
2: {},
3: {},
4: {},
5: {},
};
const arr = [1, 3, 5, 7];
const filtered = {};
for (const key of arr) {
// Note the `hasOwnProperty` check here to avoid adding the key `7` with a value of `undefined`:
if (obj.hasOwnProperty(key)) filtered[key] = obj[key];
}
console.log(filtered);
Or you could do this same thing using Array.prototype.reduce()
:
const obj ={
1: {},
2: {},
3: {},
4: {},
5: {},
};
const arr = [1, 3, 5, 7];
const filtered = arr.reduce((newObj, key) => {
// Note we add the values to `newObj` rather than `filtered` now:
if (obj.hasOwnProperty(key)) newObj[key] = obj[key];
// And you always need to return `newObj`:
return newObj;
}, { })
console.log(filtered);
Lastly, if you are already using Lodash, you could use _.pick
:
const obj ={
1: {},
2: {},
3: {},
4: {},
5: {},
};
const arr = [1, 3, 5, 7];
const filtered = _.pick(obj, arr);
console.log(filtered);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.core.min.js"></script>
Upvotes: 4
Reputation: 1074028
In a modern environment (or with appropriate polyfills), you'd use Object.entries
, Array.prototype.filter
, and Object.fromEntries
, like this:
const result = Object.fromEntries(
Object.entries(obj)
.filter(([key, value]) => arr.includes(+key))
);
Live Example:
const obj = {
1: {name: "one"},
2: {name: "two"},
3: {name: "three"},
4: {name: "four"},
5: {name: "five"},
};
const arr = [1,3,5,7];
const result = Object.fromEntries(
Object.entries(obj)
.filter(([key, value]) => arr.includes(+key))
);
console.log(result);
...but you can also take a simple loop approach:
const result = {};
for (const [key, value] of Object.entries(obj)) {
if (arr.includes(+key)) {
result[key] = value;
}
}
Live Example:
const obj = {
1: {name: "one"},
2: {name: "two"},
3: {name: "three"},
4: {name: "four"},
5: {name: "five"},
};
const arr = [1,3,5,7];
const result = {};
for (const [key, value] of Object.entries(obj)) {
if (arr.includes(+key)) {
result[key] = value;
}
}
console.log(result);
In both of the above, note that +
before key
in the filter
call. The array contains numbers, but the property keys of objects are always either strings or Symbols (strings, in your case). So we have to convert for includes
to find them.
Upvotes: 2