0

我有一个表格数组

var cars = [
   {name: "BMW X5", topsales: ["USA", "China", "Russia"], maxspeed: 250, users: ["teenage", "ladies", "mens"]}
   {name: "Volkswagen Touareg", topsales: ["USA", "Germany"], maxspeed: 240, users: ["teenage", "mens", "old mens"]}
   etc....
]

我正在尝试过滤,让我们这样说:

var query = {
   topsales: ["USA", "China"],
   users: "teenage"
}
function nestedFilter(targetArray, filters) {
     var filterKeys = Object.keys(filters);
     return targetArray.filter(function (eachObj) {
         return filterKeys.every(function (eachKey) {
             if (!filters[eachKey].length) {
                 return true; 
             }
             return filters[eachKey].includes(eachObj[eachKey]);
          });
     });
};
goodresult = nestedFilter(cars, query);

但是该功能无法正常工作。如果对象在属性中有一个值,那么它会过滤,但如果有多个,并且我需要其中至少一个来满足搜索,那么它不会过滤。帮助谁可以请

4

3 回答 3

0

我假设您打算实现一项OR功能,因为您至少说过其中一个功能。因此工作代码如下。

但在继续阅读之前,请注意以下备注:

  • 我用some代替every, 因为some作为orevery作为and. 这意味着如果当前car项目与至少一个过滤器匹配,则该行将返回 true。

  • 您应该使用item.includes(filter)而不是filter.includes(item).

  • 您需要检查当前过滤器项是否为数组,并采取相应措施。

  • 在这段代码中,我没有处理它并假设它currentCandidate是一个字符串或一个原语。如果在其他情况下候选项目(即 的字段car)本身也是一个数组,那么您必须更新代码以处理它。


  var cars = [
    {name: "BMW X5", topsales: "USA, China, Russia", maxspeed: 250, users: "teenage, ladies, men"},
    {name: "Volkswagen Touareg", topsales: "USA, Germany", maxspeed: 240, users: "teenage, men, old men"}
  ]
  
  var query = {
    topsales: ["USA", "China"],
    maxspeed: 240
  }
  
  function nestedFilter(targetArray, filters) {
    const filterKeys = Object.keys(filters);
    return targetArray.filter(function (eachObj) {
      //using some instead of every to make sure that it works as OR
      const result = filterKeys.some(function (eachKey) {
        //the current item that we are trying to use in the filter
        const currentCandidate = eachObj[eachKey];
  
        //the current item that we are using as a filter
        const currentFilterItem = filters[eachKey]
  
        if (Array.isArray(currentFilterItem)) {
          if (currentFilterItem.length === 0) {
            //no filter, return true
            return true
          }
  
          //loop on each item in the currentFilterItem
          //if any of them matches simply return true (OR)
          for (let filterKey in currentFilterItem) {
            if (currentCandidate.includes(currentFilterItem[filterKey])) {
              return true
            }
          }
          //for loop ended, no match
          return false
        } else {
          //the current filter item is not an array, use it as one item
          //return eachObj[eachKey].includes(currentFilterItem)
          return currentCandidate === currentFilterItem
        }
      });
  
      return result;
    });
  }
  
  goodresult = nestedFilter(cars, query);
  console.debug(goodresult)
于 2021-12-12T20:50:43.837 回答
0

您可以检查查询是否为数组和/或值是否为数组并进行相应检查。

function nestedFilter(data, query) {
    const
        filters = Object.entries(query);

    return data.filter(o => filters.every(([k, v]) => Array.isArray(v)
        ? Array.isArray(o[k])
            ? v.some(s => o[k].includes(s))
            : v.includes(o[k])
        : Array.isArray(o[k])
            ? o[k].includes(v)
            : o[k] === v
    ));
}

const
    cars = [{ name: "BMW X5", topsales: ["USA", "China", "Russia"], maxspeed: 250, users: ["teenage", "ladies", "mens"] }, { name: "Volkswagen Touareg", topsales: ["USA", "Germany"], maxspeed: 240, users: ["teenage", "mens", "old mens"] }],
    query = { topsales: ["USA", "China"], users: "teenage" };

console.log(nestedFilter(cars, query));

于 2021-12-12T21:09:19.157 回答
0

您可以检查“filterKey”的值是否不是数组,使其成为数组,并检查数组是否有子数组

function hasSubArray(master, sub) {
  return sub.every((i => v => i = master.indexOf(v, i) + 1)(0));
}

function nestedFilter(targetArray, filters) {
  var filterKeys = Object.keys(filters);
  return targetArray.filter(function (eachObj) {
    return filterKeys.every(function (eachKey) {
      var subArray = filters[eachKey];
      if (!Array.isArray(filters[eachKey])) {
        subArray = [filters[eachKey]];
      }

      return hasSubArray(eachObj[eachKey], subArray);
    });
  });
}
于 2021-12-12T21:48:47.627 回答