过滤任何属性包含值

时间:2017-06-01 16:36:44

标签: javascript arrays lodash

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

当我输入lea时,我想通过所有对象及其所有属性来返回包含lea的对象

当我输入italy时,我想通过所有对象及其所有属性来返回包含italy的对象。

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

欢迎

ES6lodash

  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'}]

8 个答案:

答案 0 :(得分:23)

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

使用的方法:

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; }

答案 1 :(得分:3)

使用Object.keys循环遍历对象的属性。使用reduce和filter来提高代码效率:

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

其中,术语是您的搜索字词。

答案 2 :(得分:3)

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

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

答案 3 :(得分:1)

您始终可以使用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);




答案 4 :(得分: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;
  });
}




答案 5 :(得分:0)

一种方法是使用Array#filterString#toLowerCaseString#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');

答案 6 :(得分:0)

以下是我将如何使用lodash:

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

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

答案 7 :(得分:0)

此代码检查所有嵌套值,直到找到要查找的内容,然后停止并将其返回到要在其中搜索的对象的“ array.filter”(除非找不到任何内容-返回false)。返回true时,会将对象添加到“ array.filter”方法返回的数组中。

const data = [{
    a: "a",
    b: {
      c: "c",
      d: {
        e: "e",
        f: [
          "g",
          {
            i: "i",
            j: {},
            k: []
          }
        ]
      }
    }
  },
  {
    a: "a",
    b: {
      c: "c",
      d: {
        e: "e",
        f: [
          "g",
          {
            i: "findme",
            j: {},
            k: []
          }
        ]
      }
    }
  },
  {
    a: "a",
    b: {
      c: "c",
      d: {
        e: "e",
        f: [
          "g",
          {
            i: "i",
            j: {},
            k: []
          }
        ]
      }
    }
  }
];

function getState(data: any, inputValue: string, state = false) {
  for (const value of Object.values(data)) {
    if (typeof value === 'object' && value !== null && Object.keys(value).length > 0 && state === false) {
      state = getState(value, inputValue, state);
    } else {
      if (state === false) {
        state = JSON.stringify(value).toLowerCase().includes(inputValue.toLowerCase());
      } else {
        return state;
      }
    }
  }
  return state;
}

function filter(data: [], inputValue) {
  return data.filter((element) => getState(element, inputValue));
}

console.log(filter(data, 'findme'));