如何使用lodash使用值数组过滤嵌套对象?

时间:2016-10-10 22:48:38

标签: javascript arrays filtering lodash

我有以下数据:

var jobs = [
{
 job_type: "Part Time",
 latitude: 49.545068,
 longitude: 0.760518,
 title: "reiciendis",
 industry: [
  {
    id: 1,
    name: "development" },
  { 
    id: 2,
    name: "design"
  }
 ]},
{
 job_type: "Full Time",
 latitude: 51.545068,
 longitude: 0.460518,
 title: "auteas",
 industry: [
  {
    id: 1,
    name: "development" },
  { 
    id: 2,
    name: "testing"
  }
 ]

我想尝试根据用户搜索参数过滤结果,即填充数组的求职行业选择:

var jobchoices = ["testing", "design"];
到目前为止,我的lodash过滤器看起来像这样:

var self = this

return _.filter(this.jobs, function(item) {
    return _.filter(item.industry, function(obj) {
        return _.some(self.jobchoices, obj.name);
    });
});

但是对于所有作业都返回true。这是我第一次使用lodash。我究竟做错了什么?其次,我可以继续以这种方式链接以过滤另一个用户选择,例如按作业类型吗?​​

2 个答案:

答案 0 :(得分:1)

您可以将_.filter用于您尝试检索的主数组作为最终结果,然后使用带有_.map和_.intersection的_.chain来过滤对象数组的内部。

类似于下面的代码应该足够了,尽管它并不漂亮。

var self = this;

_.filter(jobs, function(job) { 

  return _.chain(job.industry)
    .map('name')
    .intersection(self.jobchoices)
    .size()
    .gt(0)
    .value() 
})

(仅测试最新的lodash - v4.16.4)

答案 1 :(得分:1)

应该为所有作业返回true,因为示例数据jobs中的两个作业都有匹配的industry项。如果您更改jobchoices数组以使项目(或多个项目)只与您的jobs之一匹配,则可能看起来像这样(vanilla JS):

var matches = jobs.filter(function(job) {
  return job.industry.some(function(industry) {
    return jobchoices.indexOf(industry.name) > -1;
  });
});

或等同于ES6:

let matches = jobs.filter(({industry} => industry.some(({name}) => jobchoices.includes(name)));

至于你出错的地方,你的顶级_.filter还会返回另一个_.filter(这将返回一个数组 - 并且是真实的 - 因此所有项目都会被退回)。您应该可以修改原始代码,无论内部_.filter来电的长度是> 0是否可以补救:

return _.filter(this.jobs, function(item) {
    var matchingIndustries = _.filter(item.industry, function(obj) {
        return _.some(self.jobchoices, obj.name);
    });
    return matchingIndustries.length > 0;
});