过滤任何属性包含值的对象数组

问题描述 投票:0回答:9

我想知道根据字符串关键字过滤对象数组的最干净、更好的方法是什么。必须在对象的任何属性中进行搜索。

当我输入

lea
时,我想遍历所有对象及其所有属性以返回包含
lea

的对象

当我输入

italy
时,我想遍历所有对象及其所有属性以返回包含
italy
的对象。

我知道有很多解决方案,但到目前为止我只看到了一些您需要指定要匹配的属性的解决方案。

欢迎使用 ES6 和 lodash!

  const arrayOfObject = [{
      name: 'Paul',
      country: 'Canada',
    }, {
      name: 'Lea',
      country: 'Italy',
    }, {
      name: 'John',
      country: 'Italy',
    }, ];

    filterByValue(arrayOfObject, 'lea')   // => [{name: 'Lea',country: 'Italy'}]
    filterByValue(arrayOfObject, 'ita')   // => [{name: 'Lea',country: 'Italy'}, {name: 'John',country: 'Italy'}]

javascript arrays lodash
9个回答
91
投票

您可以对其进行过滤并仅搜索搜索字符串的一次出现。

使用方法:

function filterByValue(array, string) {
    return array.filter(o =>
        Object.keys(o).some(k => o[k].toLowerCase().includes(string.toLowerCase())));
}

const arrayOfObject = [{ name: 'Paul', country: 'Canada', }, { name: 'Lea', country: 'Italy', }, { name: 'John', country: 'Italy' }];

console.log(filterByValue(arrayOfObject, 'lea')); // [{name: 'Lea', country: 'Italy'}]
console.log(filterByValue(arrayOfObject, 'ita')); // [{name: 'Lea', country: 'Italy'}, {name: 'John', country: 'Italy'}]
.as-console-wrapper { max-height: 100% !important; top: 0; }


22
投票

当我们已经知道它不会是用方法搜索对象时,我们可以执行以下操作来节省时间复杂度:

function filterByValue(array, value) {
  return array.filter((data) =>  JSON.stringify(data).toLowerCase().indexOf(value.toLowerCase()) !== -1);
}

9
投票

使用Object.keys循环遍历对象的属性。使用reduce和filter让代码更加高效:

 const results = arrayOfObject.filter((obj)=>{
     return Object.keys(obj).reduce((acc, curr)=>{
           return acc || obj[curr].toLowerCase().includes(term);
     }, false);
}); 

其中 term 是您的搜索词。


5
投票

您始终可以使用

array.filter()
,然后循环遍历每个对象,如果任何值与您要查找的值匹配,则返回该对象。

const arrayOfObject = [{
      name: 'Paul',
      country: 'Canada',
    }, {
      name: 'Lea',
      country: 'Italy',
    }, {
      name: 'John',
      country: 'Italy',
    }, ];
    
let lea = arrayOfObject.filter(function(obj){
  //loop through each object
  for(key in obj){
    //check if object value contains value you are looking for
    if(obj[key].includes('Lea')){
      //add this object to the filtered array
      return obj;
      }
     }
    });
      
console.log(lea);


2
投票

一种方法是使用

Array#filter
String#toLowerCase
String#indexOf
,如下所示。

const arrayOfObject = [{
            name: 'Paul',
            country: 'Canada',
        }, {
            name: 'Lea',
            country: 'Italy',
        }, {
            name: 'John',
            country: 'Italy',
        }];

        function filterByValue(arrayOfObject, term) {
            var ans = arrayOfObject.filter(function(v,i) {
                if(v.name.toLowerCase().indexOf(term) >=0 || v.country.toLowerCase().indexOf(term) >=0) {
                    return true;
                } else false;
            });
            console.log( ans);
        }
        filterByValue(arrayOfObject, 'ita');


1
投票

这是上述版本的一个版本,它按从对象属性数组派生的值进行过滤。该函数接受对象数组和指定的对象属性键数组。

// fake ads list with id and img properties
const ads = [{
  adImg: 'https://test.com/test.png',
  adId: '1'
}, {
  adImg: 'https://test.com/test.png',
  adId: '2'
}, {
  adImg: 'https://test.com/test.png',
  adId: '3'
}, {
  adImg: 'https://test.com/test-2.png',
  adId: '4'
}, {
  adImg: 'https://test.com/test-2.png',
  adId: '5'
}, {
  adImg: 'https://test.com/test-3.png',
  adId: '6'
}, {
  adImg: 'https://test.com/test.png',
  adId: '7'
}, {
  adImg: 'https://test.com/test-6.png',
  adId: '1'
}];

// function takes arr of objects and object property
// convert arr of objects to arr of filter prop values
const filterUniqueItemsByProp = (arrOfObjects, objPropFilter) => {
  return arrOfObjects.filter((item, i, arr) => {
    return arr.map(prop => prop[objPropFilter]).indexOf(item[objPropFilter]) === i;
  });
};

const filteredUniqueItemsByProp = filterUniqueItemsByProp(ads, 'adImg');

console.log(filteredUniqueItemsByProp);


0
投票

function filterByValue(arrayOfObject,words){
  let reg = new RegExp(words,'i');
  return arrayOfObject.filter((item)=>{
     let flag = false;
     for(prop in item){
       if(reg.test(prop)){
          flag = true;
       }  
     }
     return flag;
  });
}


0
投票

这是我使用 lodash 的方法:

const filterByValue = (coll, value) =>
  _.filter(coll, _.flow(
    _.values,
    _.partialRight(_.some, _.method('match', new RegExp(value, 'i')))
  ));

filterByValue(arrayOfObject, 'lea');
filterByValue(arrayOfObject, 'ita');

0
投票

对于那些有兴趣使用

for
循环解决方案的人。

  • 外循环:迭代数组。
  • 内循环:迭代
    array[index]
  • 的对象键
  • 内循环:检查
    typeof array[index][key] === 'string'
    array[index][key]
    是否包含搜索键 -> 将
    array[index]
    存储到
    filtered
    数组。
function filterByValue(array, string) {
   let filtered = Array();

   for(let i = 0; i < array.length; i++) { 
      const keys = Object.keys(array[i]);

      for(let j = 0; j < keys.length; j++) { 
         const value = array[i][keys[j]];

         if(typeof value === 'string' &&
            value.toLowerCase().includes(string.toLowerCase())) { 

            filtered.push(array[i]);
            break;
         } else {
            continue;
         }   
      }   
   }
   
   return filtered;
}
const arrayOfObject = [
   {
      name: 'Paul',
      country: 'Canada',
   }, {
      name: 'Lea',
      country: 'Italy',
   }, {
      name: 'John',
      country: 'Italy',
   }, 
];

console.log(filterByValue(arrayOfObject, 'lea')); 
// [{name: 'Lea', country: 'Italy'}]

console.log(filterByValue(arrayOfObject, 'ita')); 
// [{name: 'Lea', country: 'Italy'}, {name: 'John', country: 'Italy'}]
© www.soinside.com 2019 - 2024. All rights reserved.