-3

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?

3 Answers3

1

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);
Rayon
  • 36,219
  • 4
  • 49
  • 76
1

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);
Robby Cornelissen
  • 91,784
  • 22
  • 134
  • 156
0

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

Andy
  • 61,948
  • 13
  • 68
  • 95