筛选所有属性值上的对象数组

Filter array of objects on all properties value

本文关键字:对象 数组 属性 筛选      更新时间:2023-09-26

我真的很惊讶我没能找到任何与我的问题有关的东西。我正在寻找一种快速的方法来过滤基于用户文本输入的对象数组。

假设我有这个数组:

let data = [{
  "id": 1,
  "first_name": "Jean",
  "last_name": "Owens",
  "email": "jowens0@google.ru",
  "gender": "Female"
}, {
  "id": 2,
  "first_name": "Marie",
  "last_name": "Morris",
  "email": "mmorris1@engadget.com",
  "gender": "Female"
}, {
  "id": 3,
  "first_name": "Larry",
  "last_name": "Wallace",
  "email": "lwallace2@example.com",
  "gender": "Male"
}];

用户写入"s",预期结果将是:

let result = [{
  "id": 1,
  "first_name": "Jean",
  "last_name": "Owens",
  "email": "jowens0@google.ru",
  "gender": "Female"
}, {
  "id": 2,
  "first_name": "Marie",
  "last_name": "Morris",
  "email": "mmorris1@engadget.com",
  "gender": "Female"
}]

我可以这样使用过滤器函数:

let = searchText = "s";
    let result = data.filter(object=>{
      for (var property in object) {
        if (object.hasOwnProperty(property)) {
          return object[property].toString().toLowerCase().indexOf(searchText) !== -1;
        }
      }
    });

所以我想知道是否有更好的替代方案来解决这个问题?

——这是一个工作的JsFiddle感谢KoolShams

—Plunker用于基准测试(使用2k数据进行测试)

您可以使用Object.keys()some()

let data = [{
  "id": 1,
  "first_name": "Jean",
  "last_name": "Owens",
  "email": "jowens0@google.ru",
  "gender": "Female"
}, {
  "id": 2,
  "first_name": "Marie",
  "last_name": "Morris",
  "email": "mmorris1@engadget.com",
  "gender": "Female"
}, {
  "id": 3,
  "first_name": "Larry",
  "last_name": "Wallace",
  "email": "lwallace2@example.com",
  "gender": "Male"
}];
var result = data.filter(function(o) {
  return Object.keys(o).some(function(k) {
    return o[k].toString().toLowerCase().indexOf('s') != -1;
  })
})
console.log(result)

可以用Object.keys省略hasOwnProperty

此解决方案具有箭头函数。

let data = [{ "id": 1, "first_name": "Jean", "last_name": "Owens", "email": "jowens0@google.ru", "gender": "Female" }, { "id": 2, "first_name": "Marie", "last_name": "Morris", "email": "mmorris1@engadget.com", "gender": "Female" }, { "id": 3, "first_name": "Larry", "last_name": "Wallace", "email": "lwallace2@example.com", "gender": "Male" }],
    searchText = "s",
    result = data.filter(o => 
        Object.keys(o).some(k => 
            o[k].toString().toLowerCase().indexOf(searchText) !== -1));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

为了获得更好的性能,您可以提前存储键并迭代键,如果数组中的所有对象是统一的,则无需对它们使用Object.keys

let data = [{ "id": 1, "first_name": "Jean", "last_name": "Owens", "email": "jowens0@google.ru", "gender": "Female" }, { "id": 2, "first_name": "Marie", "last_name": "Morris", "email": "mmorris1@engadget.com", "gender": "Female" }, { "id": 3, "first_name": "Larry", "last_name": "Wallace", "email": "lwallace2@example.com", "gender": "Male" }],
    keys = Object.keys(data[0]),
    searchText = "s",
    result = data.filter(o => 
        keys.some(k => 
            o[k].toString().toLowerCase().indexOf(searchText) !== -1));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

那么,您可以使用任何lodash的集合相关的函数来对象,它将遍历值。你也可以直接使用_.toLower对任何字符串或数字或布尔值,它将处理所有角落的情况,所以如果你想要一个更简单的解决方案,和良好的结构代码,那么你去:

data.filter(o=>_.some(o, v => _.toLower(v).indexOf('s')>-1))

下面是工作示例:

let data = [{
  "id": 1,
  "first_name": "Jean",
  "last_name": "Owens",
  "email": "jowens0@google.ru",
  "gender": "Female"
}, {
  "id": 2,
  "first_name": "Marie",
  "last_name": "Morris",
  "email": "mmorris1@engadget.com",
  "gender": "Female"
}, {
  "id": 3,
  "first_name": "Larry",
  "last_name": "Wallace",
  "email": "lwallace2@example.com",
  "gender": "Male"
}];
var sTxt = 's';
var res = data.filter(o=>_.some(o, v =>_.toLower(v).indexOf(sTxt)>-1))
console.log('Result: ', JSON.stringify(res,null,'    '));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>