简体   繁体   中英

How to filter array of objects by object keys?

I try to filter array of object items by keys fields :

const items = [{id: 1, name: "OP"}];
const fields = ['id', 'name'];
const value = 1;

   return items.filter((singleItem) => {
      fields.forEach((field) => {
        singleItem[field].toLowerCase().includes(value.toLowerCase())
      })
    })

But How to return found result back to filter?

The ideal use case for Array#find . Also, the return keyword is missing in your snippet.

I have used toString() to convert all the inputs to string before invoking toLowerCase method as it does not work on Number .

 let items = [{ id: 1, name: "abc" }, { id: 2, name: "xyz" }]; let fields = ['id', 'name']; let value = 'xyz'; let op = items.filter((singleItem) => { return fields.find((field) => singleItem[field].toString().toLowerCase().includes(value.toLowerCase())) }); console.log(op);

You can use some() :

 const items = [{id: 1, name: "OP"}]; const fields = ['id', 'name']; const value = 1; const result = items.filter(item => fields.some(field => ('' + item[field]).toLowerCase().includes(('' + value).toLowerCase()))); console.log(result);

Considering that your original logic had a case conversion and a call to includes() , I'm converting everything to strings by appending to '' .


From a DRY perspective, it would probably be nicer to split off the canonicalization into a separate function:

 const items = [{id: 1, name: "OP"}]; const fields = ['id', 'name']; const value = 1; const canonicalize = (x) => ('' + x).toLowerCase(); const result = items.filter(item => fields.some(field => canonicalize(item[field]).includes(canonicalize(value)))); console.log(result);

You can use some (or maybe every depending on your required output).

[ some ] returns true if, in the array, it finds an element for which the provided function returns true; otherwise it returns false.

Instead of includes I would use a direct comparison. Additionally you can't call toLowerCase on a number. You could coerce it to a string and then check it against the lowercase value, but in this example I've left that out. I think the value you pass into the function should be the correct type that you look for in the objects.

 const items = [{id: 1, name: 'OP'},{id: 2, name: 'OP'}]; const fields = ['id', 'name']; function fn(value) { return items.filter(item => { return Object.values(item).some(v => { return v === value; }); }) } console.log(fn(1)); console.log(fn('1')); console.log(fn('OP'));

Additional documentation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM