繁体   English   中英

搜索/过滤 JavaScript 对象数组

[英]Search/Filter JavaScript Object Array

我正在尝试创建一个搜索/过滤器函数,它允许用户过滤一个 JS 对象数组,该数组返回一个填充了与搜索查询匹配的数据的数组。

例如,我希望能够在一个查询中搜索多个属性; 如果我搜索HKG ,它将返回所有 3 个对象,但如果我搜索HKG 12345 ,它将返回数组中的第一个对象。

另一个示例是,如果我要搜索8 ,它将从与查询匹配的sumOfContainers属性返回数组中的前 2 个对象,但如果我搜索8 SAV ,它将仅返回第一个对象。

results = [];

objects = [
        {laneId:"12345", lane:"HKG-SAV", equipmentType:"20'STD", sumOfContainers: "8", baseline:"$1234", new:"$1234", newSaving:"$1234"},
        {laneId:"12346", lane:"HKG-FRA", equipmentType:"20'STD", sumOfContainers: "8", baseline:"$1234", new:"$1234", newSaving:"$1234"},
        {laneId:"12347", lane:"HKG-LAX", equipmentType:"20'STD", sumOfContainers: "9", baseline:"$1234", new:"$1234", newSaving:"$1234"},     
];

const Search = (toSearch) => {
 for(var i=0; i<objects.length; i++) {
   for(key in objects[i]) {
     if(objects[i][key].indexOf(toSearch)!=-1) {
       results.push(objects[i]);
     }
   }
  }
}

我尝试的问题是它会返回重复的数据。 我在网上遇到了很多帖子,但我发现很难找到寻求类似结果的帖子。

我正在尝试使用本机 JavaScript 来实现这一点。

一些问题:

  • 添加重复项是因为在添加对象后,您会继续在同一对象中寻找更多匹配项。 所以如果有任何其他键匹配,相同的对象将被添加两次

  • 当搜索包含空格时,您的描述说您希望将其视为多个搜索词的分隔符,但您的代码永远不会像那样拆分搜索参数。

  • 您的函数中没有return语句

  • 关键变量没有用varletconst

我建议用filter解决这个问题:这保证你不会得到重复。 然后要求所有搜索词都匹配:为此,您可以使用splitevery 然后要求至少有一个与搜索词匹配的键:为此,您可以使用some

不要用 PascalCase 命名你的搜索函数,而是用驼峰命名(所以用search而不是Search )。 通常的做法是 PascalCase 保留用于构造函数/类名称。

const search = toSearch => {
 let terms = toSearch.split(" ");
 return objects.filter(object =>
   terms.every(term =>
     Object.values(object).some(value =>
       value.includes(term)
     )
   )
  );
}

我想出了一种非常糟糕的方法来实现问题中的条件。 如果有人可以使此代码更加优化,那就太棒了。

  const search = () => {
      let toSearch = document.getElementById("search").value;
      let lanes = this.objects;
      let result = [];
      const filters = toSearch.split(" ");
      for(let i = 0; i <lanes.length; i++) {
        let search = "";
        let isMatched = true;
        for(let key in lanes[i]) {
            search += lanes[i][key] + " ";
        }
        filters.forEach(filter => {
          if(search.indexOf(filter) == -1) {
            isMatched = false;
            break;
          } 
        });
        if(isMatched) {
          result.push(lanes[i]);
        }
      }
      return result;
    }

如果你不介意lodash

const _ = require('lodash');

const objects = [
        {laneId:"12345", lane:"HKG-SAV", equipmentType:"20'STD", sumOfContainers: "8", baseline:"$1234", new:"$1234", newSaving:"$1234"},
        {laneId:"12346", lane:"HKG-FRA", equipmentType:"20'STD", sumOfContainers: "8", baseline:"$1234", new:"$1234", newSaving:"$1234"},
        {laneId:"12347", lane:"HKG-LAX", equipmentType:"20'STD", sumOfContainers: "9", baseline:"$1234", new:"$1234", newSaving:"$1234"},     
];

const mySearch = (arr, text) => {
  const includesValue = (word, obj) => _.some(obj, (value) => _.includes(value, word));
  const words = _.words(text); 
  return arr
    .filter((obj) => 
      words.every((word) => 
        includesValue(word, obj)
      )
    );
};

console.log(mySearch(objects, 'HKG 12345'));
// [{laneId: '12345', lane: 'HKG-SAV', equipmentType: "20'STD", sumOfContainers: '8', baseline: '$1234', new: '$1234', newSaving: '$1234' }]

console.log(mySearch(objects, '8'));
// [
//   {laneId:"12345", lane:"HKG-SAV", equipmentType:"20'STD", sumOfContainers: "8", baseline:"$1234", new:"$1234", newSaving:"$1234"},
//   {laneId:"12346", lane:"HKG-FRA", equipmentType:"20'STD", sumOfContainers: "8", baseline:"$1234", new:"$1234", newSaving:"$1234"},
// ]

console.log(mySearch(objects, '8 SAV'));
// [{laneId: '12345', lane: 'HKG-SAV', equipmentType: "20'STD", sumOfContainers: '8', baseline: '$1234', new: '$1234', newSaving: '$1234' }]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM