【问题标题】:Filtering array of objects with multiple properties getting empty as result过滤具有多个属性的对象数组,结果为空
【发布时间】:2019-11-04 20:00:38
【问题描述】:

这是我尝试获得多个属性的结果。但结果总是空数组。

有人在这里向我展示正确和最小的方法吗?我也没有不同的过滤条件..

nestedFilter = (targetArray, filters) => {
          var filterKeys = Object.keys(filters);
          return targetArray.filter(function (eachObj) {
            return filterKeys.every(function (eachKey) {
              return filters[eachKey].includes(eachObj[eachKey]);
           });
       });
    };

//filter 1    
let filter1 = {
  color: "Blue",
  size:'70'
};
//filter 2
let filter2 = {
  name:'',
  color: "Blue",
  size:'70'
};

//filter 3
let filters = {
    name:'',
  color: "",
  size:''
};


let products = [
  { name: "A", color: "Blue", size: 50 },
  { name: "B", color: "Blue", size: 60  },
  { name: "C", color: "Black", size: 70 },
  { name: "D", color: "Green", size: 50 },
];

var results = nestedFilter(products, filter2);

console.log(results); //getting alwasy empty.

Live Demo here

【问题讨论】:

  • 您没有任何名称为空的产品
  • @CodeManiac - 请检查我有多个过滤条件。
  • 您在 filters[eachKey].includes(eachObj[eachKey]) 中搜索,这始终是错误的,因为您在过滤器中的键都没有值
  • 在你的过滤器中你有name: ''所以你没有一个产品的名字是""所以在这种情况下想要的结果是什么
  • @CodeManiac - 而不是 includes 我尝试使用 contains 但仍然没有运气

标签: javascript arrays object ecmascript-6 ecmascript-2016


【解决方案1】:

如果任何一个值匹配,您需要使用一些,因为您希望产品包含在输出中

let products = [{name: "A",color: "Blue",size: 50},{name: "B",color: "Blue",size: 60},{name: "C",color: "Black",size: 70},{name: "D",color: "Green",size: 50},];


let filter1 = {color: "Blue",size: '70'};
let filter2 = {name: '',color: "Blue",size: '70'};
let filters = {name: '',color: "",size: ''};

const nestedFilter = (targetArray, filters) => {
  var filterKeys = Object.keys(filters);
  return targetArray.filter(function(eachObj) {
    return filterKeys.some(function(eachKey) {
      return filters[eachKey].includes(eachObj[eachKey]);
    });
  });
};


console.log(nestedFilter(products, filter1))
console.log(nestedFilter(products, filter2))
console.log(nestedFilter(products, filters))

【讨论】:

  • 其实console.log(nestedFilter(products, filters))需要全部退回。应该考虑根本没有过滤器。
【解决方案2】:

您应该使用some 而不是every。另请注意,您可以利用嵌套返回和其他功能使您的代码更简洁。

const nestedFilter = (targetArray, filters) => targetArray.filter(o => Object.keys(filters).some(k => filters[k].includes(o[k]) || filters[k] == ""));
 
let filter1 = {color:"Blue",size:'70'};
let filter2 = {name:'',color:"Blue",size:'70'};
let filters = {name:'',color:"",size:''};
let products = [{name:"A",color:"Blue",size:50},{name:"B",color:"Blue",size:60},{name:"C",color:"Black",size:70},{name:"D",color:"Green",size:50},];

console.log(nestedFilter(products, filter1));
console.log(nestedFilter(products, filter2));
console.log(nestedFilter(products, filters));
.as-console-wrapper { max-height: 100% !important; top: auto; }

【讨论】:

  • 没有过滤器的地方都是空的,比如filters - 我需要返回所有对象而不是空的。
  • 您可以更新以匹配所有条件,而不是使用某些条件匹配任何条件?对于该方法需要使用什么?
【解决方案3】:

您也可以使用 Object.entriesArray.filter 解决此问题 和Array.some 像这样:

let products = [
  { name: "A", color: "Blue", size: 50 },
  { name: "B", color: "Blue", size: 60  },
  { name: "C", color: "Black", size: 70 },
  { name: "D", color: "Green", size: 50 },
];

let filter1 = { color: 'Blue', size:  '70' }
let filter2 = { name:  '', color: 'Blue', size:  '60' }
let filter3 = { name:  '', color: '', size:  '' }

let nestedFilter = (arr, filter) => {
  let fE = Object.entries(filter)
  return arr.filter(f => fE.some(([k,v]) => !v || f[k].toString().includes(v)))
}

console.log(nestedFilter(products, filter1))  // 3 objects
console.log(nestedFilter(products, filter2))  // 4 objects
console.log(nestedFilter(products, filter3))  // 4 objects

我们的想法是获取您正在使用的过滤器的entries,然后使用它的键/值来检查是否首先没有值是true(我们想要过滤器键匹配的记录)空字符串)以及实际值是否与当前过滤对象键的值匹配。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 2016-08-03
    • 1970-01-01
    • 2018-08-17
    • 1970-01-01
    • 2021-07-05
    • 2021-04-21
    相关资源
    最近更新 更多