使用lodash在JSON数组中根据多个键过滤多个值

5
我有一些动态数据,每次可能有不同的键值对需要在不同的数据中进行过滤。如何使用lodash中的多个键值来过滤它?我正在使用它的filter函数,但结果无法实现。
示例数据:
    var data = [ {
  "VOTER" : 1012,
  "PARTY" : "REPUBLICAN",
  "PRECINCT" : 2408,
  "AGE_GROUP" : "71 +",
  "LAST_VOTED" : "08/2006",
  "YEARS_REG" : 51,
  "BALLOT_STATUS" : "PERM"
}, {
  "VOTER" : 1013,
  "PARTY" : "REPUBLICAN",
  "PRECINCT" : 2411,
  "AGE_GROUP" : "71 +",
  "LAST_VOTED" : "08/2006",
  "YEARS_REG" : 50,
  "BALLOT_STATUS" : "PERM"
}, {
  "VOTER" : 1014,
  "PARTY" : "DEMOCRAT",
  "PRECINCT" : 2424,
  "AGE_GROUP" : "71 +",
  "LAST_VOTED" : "08/2006",
  "YEARS_REG" : 50,
  "BALLOT_STATUS" : "PERM"
}, {
  "VOTER" : 1015,
  "PARTY" : "DEMOCRAT",
  "PRECINCT" : 2418,
  "AGE_GROUP" : "71 +",
  "LAST_VOTED" : "08/2006",
  "YEARS_REG" : 50,
  "BALLOT_STATUS" : "POLL"
    },{
  "VOTER" : 1109,
  "PARTY" : "AMERICAN INDEP",
  "PRECINCT" : 2404,
  "AGE_GROUP" : "71 +",
  "LAST_VOTED" : "08/2006",
  "YEARS_REG" : 34,
  "BALLOT_STATUS" : "POLL"
},{
  "VOTER" : 1111,
  "PARTY" : "DECLINED",
  "PRECINCT" : 2414,
  "AGE_GROUP" : "71 +",
  "LAST_VOTED" : "08/2006",
  "YEARS_REG" : 34,
  "BALLOT_STATUS" : "POLL"
}

]

过滤器对象是:
var filterby = {"PARTY":["REPUBLICAN","DEMOCRAT"],"BALLOT_STATUS":["PERM","POLL"]}
lodash中的过滤函数:
var filtered_data = _.filter(data, filterby);
3个回答

11
你可以使用纯JavaScript迭代filterBy的键和值。

var data = [{ VOTER: 1012, PARTY: "REPUBLICAN", PRECINCT: 2408, AGE_GROUP: "71 +", LAST_VOTED: "08/2006", YEARS_REG: 51, BALLOT_STATUS: "PERM" }, { VOTER: 1013, PARTY: "REPUBLICAN", PRECINCT: 2411, AGE_GROUP: "71 +", LAST_VOTED: "08/2006", YEARS_REG: 50, BALLOT_STATUS: "PERM" }, { VOTER: 1014, PARTY: "DEMOCRAT", PRECINCT: 2424, AGE_GROUP: "71 +", LAST_VOTED: "08/2006", YEARS_REG: 50, BALLOT_STATUS: "PERM" }, { VOTER: 1015, PARTY: "DEMOCRAT", PRECINCT: 2418, AGE_GROUP: "71 +", LAST_VOTED: "08/2006", YEARS_REG: 50, BALLOT_STATUS: "POLL" }, { VOTER: 1109, PARTY: "AMERICAN INDEP", PRECINCT: 2404, AGE_GROUP: "71 +", LAST_VOTED: "08/2006", YEARS_REG: 34, BALLOT_STATUS: "POLL" }, { VOTER: 1111, PARTY: "DECLINED", PRECINCT: 2414, AGE_GROUP: "71 +", LAST_VOTED: "08/2006", YEARS_REG: 34, BALLOT_STATUS: "POLL" }],
    filterBy = { PARTY: ["REPUBLICAN", "DEMOCRAT"], BALLOT_STATUS: ["PERM", "POLL"] },
    result = data.filter(function (o) {
        return Object.keys(filterBy).every(function (k) {
            return filterBy[k].some(function (f) {
                return o[k] === f;
            });
        });
    });

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

ES6

var data = [{ VOTER: 1012, PARTY: "REPUBLICAN", PRECINCT: 2408, AGE_GROUP: "71 +", LAST_VOTED: "08/2006", YEARS_REG: 51, BALLOT_STATUS: "PERM" }, { VOTER: 1013, PARTY: "REPUBLICAN", PRECINCT: 2411, AGE_GROUP: "71 +", LAST_VOTED: "08/2006", YEARS_REG: 50, BALLOT_STATUS: "PERM" }, { VOTER: 1014, PARTY: "DEMOCRAT", PRECINCT: 2424, AGE_GROUP: "71 +", LAST_VOTED: "08/2006", YEARS_REG: 50, BALLOT_STATUS: "PERM" }, { VOTER: 1015, PARTY: "DEMOCRAT", PRECINCT: 2418, AGE_GROUP: "71 +", LAST_VOTED: "08/2006", YEARS_REG: 50, BALLOT_STATUS: "POLL" }, { VOTER: 1109, PARTY: "AMERICAN INDEP", PRECINCT: 2404, AGE_GROUP: "71 +", LAST_VOTED: "08/2006", YEARS_REG: 34, BALLOT_STATUS: "POLL" }, { VOTER: 1111, PARTY: "DECLINED", PRECINCT: 2414, AGE_GROUP: "71 +", LAST_VOTED: "08/2006", YEARS_REG: 34, BALLOT_STATUS: "POLL" }],
    filterBy = { PARTY: ["REPUBLICAN", "DEMOCRAT"], BALLOT_STATUS: ["PERM", "POLL"] },
    result = data.filter(o => Object.keys(filterBy).every(k => filterBy[k].some(f => o[k] === f)));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }


你好,我知道现在问有点晚了,但我正在使用您的代码进行过滤,但出现了一个错误,提示“some不是函数”,请问能否帮忙解决一下? - Rahul Dudharejiya
@RahulDudharejiya,你需要与上面相同的对象结构来使用 filterBy 方法,包含属性和数组作为值,因为你需要使用 Array 原型中的方法。请添加一个示例所取的对象。 - Nina Scholz
@NinaScholz 你好,虽然有点晚了,但如果Json数组是嵌套的,该如何修改呢?我想使用投票者和状态值进行过滤。例如:[{ "VOTER" : 1012, "PARTY" : "REPUBLICAN", "PRECINCT" : 2408, "AGE_GROUP" : "71 +", "LAST_VOTED" : "08/2006", "YEARS_REG" : 51, "BALLOT_STATUS" : "PERM" "vehicleStatusHistory": { "id": 721, "Ind": "Y", "status": { "StatusId": 3, "StatusVal": "In-Transit" } }, } ] - Nandha Kumar
这是关于编程的内容,需要将其翻译成中文。请提出一个新的问题,并附上您尝试过的代码和所需的结果。 - Nina Scholz
真正值得的解决方案。 - deva11
@NinaScholz,你的回答中包含了很多JavaScript/ES6的技巧,对我帮助很大。非常感谢。如果在每个嵌套层次中加入一些注释,会让我更快地理解。 - JJJSchmidt

4

_.filter 方法不允许您指定多个筛选选项。尝试通过传递自定义筛选函数来解决:

_.filter(data, function (item) {
  return ['REPUBLICAN', 'DEMOCRAT'].indexOf(item.PARTY) >= 0
      && ['PERM', 'POLL'].indexOf(item.BALLOT_STATUS) >= 0
})

感谢@hsz的回答,但是filterby将是动态的,我不知道可能会有2个、3个或5个键值对,例如可能会有: var filterby = {"PARTY":["REPUBLICAN","DEMOCRAT"],"BALLOT_STATUS":["PERM","POLL"],"VOTER":"1014"} - Mayur
所以使用变量代替。 - hsz
你能指导我吗? - Mayur

0

_.filter 函数遍历集合的元素,第一个参数是集合本身,在你的例子中是 data,第二个参数应该是一个函数,每次迭代时都会调用它,更多信息请参见 文档

在你的示例中,你可以使用 箭头函数

请查看以下代码片段以获取更多信息。

将你的 filterby 变量更改为以下内容

var filterby = (m) => { return m => m.PARTY == "REPUBLICAN" || m.PARTY == "DEMOCRAT" && m.BALLOT_STATUS == "PERM" || m.BALLOT_STATUS == "POLL"  };

var data = [ {
  "VOTER" : 1012,
  "PARTY" : "REPUBLICAN",
  "PRECINCT" : 2408,
  "AGE_GROUP" : "71 +",
  "LAST_VOTED" : "08/2006",
  "YEARS_REG" : 51,
  "BALLOT_STATUS" : "PERM"
}, {
  "VOTER" : 1013,
  "PARTY" : "REPUBLICAN",
  "PRECINCT" : 2411,
  "AGE_GROUP" : "71 +",
  "LAST_VOTED" : "08/2006",
  "YEARS_REG" : 50,
  "BALLOT_STATUS" : "PERM"
}, {
  "VOTER" : 1014,
  "PARTY" : "DEMOCRAT",
  "PRECINCT" : 2424,
  "AGE_GROUP" : "71 +",
  "LAST_VOTED" : "08/2006",
  "YEARS_REG" : 50,
  "BALLOT_STATUS" : "PERM"
}, {
  "VOTER" : 1015,
  "PARTY" : "DEMOCRAT",
  "PRECINCT" : 2418,
  "AGE_GROUP" : "71 +",
  "LAST_VOTED" : "08/2006",
  "YEARS_REG" : 50,
  "BALLOT_STATUS" : "POLL"
    },{
  "VOTER" : 1109,
  "PARTY" : "AMERICAN INDEP",
  "PRECINCT" : 2404,
  "AGE_GROUP" : "71 +",
  "LAST_VOTED" : "08/2006",
  "YEARS_REG" : 34,
  "BALLOT_STATUS" : "POLL"
},{
  "VOTER" : 1111,
  "PARTY" : "DECLINED",
  "PRECINCT" : 2414,
  "AGE_GROUP" : "71 +",
  "LAST_VOTED" : "08/2006",
  "YEARS_REG" : 34,
  "BALLOT_STATUS" : "POLL"
}

]



//var filterby = {"PARTY":["REPUBLICAN","DEMOCRAT"],"BALLOT_STATUS":["PERM","POLL"]}

var filterby = (m) => { return m => m.PARTY == "REPUBLICAN" || m.PARTY == "DEMOCRAT" && m.BALLOT_STATUS == "PERM" || m.BALLOT_STATUS == "POLL"  };


var filtered_data = _.filter(data, filterby);
console.log(filtered_data);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接