簡體   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