【问题标题】:Use dictionary to filter javascript data object使用字典过滤 javascript 数据对象
【发布时间】:2018-08-02 22:28:04
【问题描述】:

假设我有一个过滤器:

filter = [ {key: "pl", value: 3}, {key: "sh", value: 2} ]

我想用上述过滤条件过滤以下javascript对象:

var data = [
{title: "The Uncertainty of the Poet ",
pl: 3,
si: 2,
va: 3,
te: 0,
co: 0,
or: 4,
sh: 2,
po: 0,
li: 0,
ar: 5
},
{
title: "Direction",
pl: 4,
si: 3,
va: 1,
te: 3,
co: 0,
or: 3,
sh: 2,
po: 0,
li: 0,
ar: 5
}
...
]

我尝试了以下方法,但没有成功:

var result = data.filter(function(d){
            for (item in filter) {
                return d.key==d.value;
            }

【问题讨论】:

  • 您的预期结果是什么?如果过滤器匹配,是否要返回整个对象?
  • 我想返回只包含符合过滤条件的条目的对象

标签: javascript dictionary filter


【解决方案1】:

检查对象是否满足所有条件的另一个潜在选项:

data.filter(function(obj) {
    return filter.reduce(function(a, f) {
        return a && (obj[f.key] === f.value);
    }, true);
});

由于使用了reduce,因此无需检查 hasOwnProperty 即可工作。如果您想检查任何过滤条件是否为真,您可以将其更改为

data.filter(function(obj) {
    return filter.reduce(function(a, f) {
        return a || (obj[f.key] === f.value);
    }, false);
});

【讨论】:

  • 谢谢你。第一个工作如我所愿。由于我的过滤条件是动态更新的,它返回的数据对象包含满足所有选择并存储在过滤器中的条件的条目。
【解决方案2】:

你也可以这样做:

var filters = [{key: "pl", value: 3}, {key: "sh", value: 2}]

var data = [
    {
        title: "The Uncertainty of the Poet ",
        pl: 2,
        si: 2,
        va: 3,
        te: 0,
        co: 0,
        or: 4,
        sh: 3,
        po: 0,
        li: 0,
        ar: 5
    },
    {
        title: "Direction",
        pl: 3,
        si: 3,
        va: 1,
        te: 3,
        co: 0,
        or: 3,
        sh: 2,
        po: 0,
        li: 0,
        ar: 5
    }
]

var result = data.filter((item) => {
  for(let i = 0; i < filters.length; ++i) {
    let filter = filters[i];

    if(item[filter.key] && item[filter.key] === filter.value) {
      return true;
    }
  }

  return false;
});

【讨论】:

    【解决方案3】:

    如果您希望它匹配一个或其他值,这将起作用:

    match = [ {key: "pl", value: 3}, {key: "sh", value: 2} ]
    
    var result = data.filter(function(d) {
        return d.pl === match[0]['value'] || d.sh === match[1]['value']
    })
    

    我已将数组名称更改为 match 以避免混淆。

    【讨论】:

    • 如果过滤器数组有 3 个(或更多)元素并且每个对象中的键是未知的怎么办?
    【解决方案4】:

    您的for in 不够深入。它在数组上循环,而不是处理数组中的每个对象

    可以使用Array#every() 确保过滤器数组中的每个对象在数据对象中都匹配

    // filter main data
    var result = data.filter(function(dataObj){
       // check if all proprties within filter array are a match
       return filter.every(function(filterObj){
          //compare value of property found in filterObject with value 
          return dataObj[filterObj.key] === filterObj.value
       })
    })
    
    console.log(result)
    <script>
    var filter = [ {key: "pl", value: 2}, {key: "sh", value: 3} ]
    
    var data = [{
        title: "The Uncertainty of the Poet ",
        pl: 2,
        si: 2,
        va: 3,
        te: 0,
        co: 0,
        or: 4,
        sh: 3,
        po: 0,
        li: 0,
        ar: 5
      },
      {
        title: "Direction",
        pl: 4,
        si: 3,
        va: 1,
        te: 3,
        co: 0,
        or: 3,
        sh: 2,
        po: 0,
        li: 0,
        ar: 5
      }
     
    ]
    </script>

    【讨论】:

    • 我认为我们可能需要检查该属性是否存在以防万一。所以像 dataObj[filterObj.key] && dataObj[filterObj.key] === filterObj.value
    • @KeyvanSadralodabai 如果它不存在只会简单地=== undefined 并且不会匹配或抛出错误
    • @KeyvanSadralodabai 简单示例var foo={a:1}; console.log(foo.bar)//undefined
    • 是的,我已经测试过了。我删除了我的答案,因为它没有添加任何有用的东西。
    • @KeyvanSadralodabai 只有在涉及嵌套属性时才会有问题
    猜你喜欢
    • 1970-01-01
    • 2018-01-27
    • 2020-05-23
    • 1970-01-01
    • 2017-01-28
    • 2023-04-09
    • 2018-10-07
    • 2020-12-03
    • 1970-01-01
    相关资源
    最近更新 更多