0

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?

3
  • whats the enter code here? And when does it not work? you have example data? the code looks good Commented Jan 4, 2020 at 14:37
  • 1
    Your code is fine. What errors do you encountered when it doesn't work? Commented Jan 4, 2020 at 14:47
  • obj[e] ? is not a proper check (cause falsy values might not be what you want to check for). e in obj ? would be more accurate. Commented Jan 4, 2020 at 15:02

2 Answers 2

4

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>

Sign up to request clarification or add additional context in comments.

Comments

2

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.