最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript how to filter an array using forEach() inside filter() - Stack Overflow

programmeradmin2浏览0评论

I have an array of objects and I'd like to filter it based on the objects property values. I'd like to filter it by different properties, so it needed to be dynamic. For this I have an input field where I type and then filter the array. So, let's say I have these 2 different arrays:

const array_one = [
  {id: 1, code: 'ABC123', name: 'John'},
  {id: 2, code: 'DEF456', name: 'Stew'},
    // ...
];

const array_two = [
  {id: 1, value: '012345', company: 'Company 01' },
  {id: 2, value: '678910', company: 'Company 02' },
    // ...
];

I want a function where I can filter the first array based on the name, also If I want to filter the second array, I want to filter it by the value.

For this, I built this function:

filterArray(array: Array<any>, fields: Array<any>, value: string) {
    value = this.convertString(value);

    array = array.filter((item) => {
        fields.forEach(obj => {
            if ( item[obj] ) {
                const _newObj = this.convertString(item[obj]);
                if ( _newObj.indexOf(value) !== -1 ) {
                    console.log(item);
                    return item;
                }
            }
        });
    });

    return array;
}
// convertString() is just another function to replace accents, spaces, etc...

Then I call it like this:

filterArray(originalArray, ['name'], valueFromInput);

// or...
filterArray(originalArray, ['value'], valueFromInput);

// or even...
filterArray(originalArray, ['value', 'company'], valueFromInput);

But the array filtered is always returnin empty, even if the console inside the indexOf verification prints the correct object on the console.

What am I doing wrong here? Because it's filtering properly, I have manually checked it, but it doesn't add to the new filtered array.

I have an array of objects and I'd like to filter it based on the objects property values. I'd like to filter it by different properties, so it needed to be dynamic. For this I have an input field where I type and then filter the array. So, let's say I have these 2 different arrays:

const array_one = [
  {id: 1, code: 'ABC123', name: 'John'},
  {id: 2, code: 'DEF456', name: 'Stew'},
    // ...
];

const array_two = [
  {id: 1, value: '012345', company: 'Company 01' },
  {id: 2, value: '678910', company: 'Company 02' },
    // ...
];

I want a function where I can filter the first array based on the name, also If I want to filter the second array, I want to filter it by the value.

For this, I built this function:

filterArray(array: Array<any>, fields: Array<any>, value: string) {
    value = this.convertString(value);

    array = array.filter((item) => {
        fields.forEach(obj => {
            if ( item[obj] ) {
                const _newObj = this.convertString(item[obj]);
                if ( _newObj.indexOf(value) !== -1 ) {
                    console.log(item);
                    return item;
                }
            }
        });
    });

    return array;
}
// convertString() is just another function to replace accents, spaces, etc...

Then I call it like this:

filterArray(originalArray, ['name'], valueFromInput);

// or...
filterArray(originalArray, ['value'], valueFromInput);

// or even...
filterArray(originalArray, ['value', 'company'], valueFromInput);

But the array filtered is always returnin empty, even if the console inside the indexOf verification prints the correct object on the console.

What am I doing wrong here? Because it's filtering properly, I have manually checked it, but it doesn't add to the new filtered array.

Share Improve this question edited Jul 9, 2017 at 14:18 Alireza 105k27 gold badges277 silver badges173 bronze badges asked Jul 9, 2017 at 14:17 celsomtrindadecelsomtrindade 4,67118 gold badges64 silver badges124 bronze badges 2
  • 1 Please be more clear as to what result you're expecting. When using forEach(), returning something in the callback won't have any effect. If you wan't to map each item to something else, use map(). If you're defining a function body, like you do for your filter() callback, you have to use the return keyword otherwise that callback will implicitly return undefined – Lennholm Commented Jul 9, 2017 at 14:24
  • 1 In JavaScript, forEach doesn't have a return value, so when you return item it's just being ignored. But filter requires a return value that can be coerced to a truthy or falsely value. You're not returning anything inside of filter, which is why you're not getting a filtered array. – shadymoses Commented Jul 9, 2017 at 14:25
Add a comment  | 

2 Answers 2

Reset to default 12

You can iterate the fields using Array#some, and if one of them is equal to value return the item:

const array_one = [
  {id: 1, code: 'ABC123', name: 'John'},
  {id: 2, code: 'DEF456', name: 'Stew'}
];

const array_two = [
  {id: 1, value: '012345', company: 'Company 01' },
  {id: 2, value: '678910', company: 'Company 02' }
];

const filterArray = (array, fields, value) => {
  fields = Array.isArray(fields) ? fields : [fields];
  
  return array.filter((item) => fields.some((field) => item[field] === value));
};
  
console.log(filterArray(array_one, 'name', 'Stew'));

console.log(filterArray(array_two, ['id', 'company'], 2));

console.log(filterArray(array_two, ['id', 'company'], 'Company 02'));

If you want to make the filter about more than one filed then the value that you send it to the function, should be also array. In my code below I assume that you want to return the object that Achieves all conditions (contains all properties that you send to the function with the same value)

 const array_one = [
      {id: 1, code: 'ABC123', name: 'John'},
      {id: 2, code: 'DEF456', name: 'Stew'},
   ];

   const array_two = [
      {id: 1, value: '012345', company: 'Company 01' },
      {id: 2, value: '678910', company: 'Company 02' },
   ];

   function filterArray(array, fields, value) {
       array = array.filter((item) => {
           const found = fields.every((field, index) => { 
               return item[field] && item[field] === value[index]
           })
           return found
       });
       return array;
   }

   console.log(filterArray(array_one, ['name'], ['Stew']));

   console.log(filterArray(array_two, ['id', 'company'], [1,'Company 01']));
发布评论

评论列表(0)

  1. 暂无评论