【问题标题】:How do I retrieve a list of active items from an Array?如何从数组中检索活动项目列表?
【发布时间】:2019-04-16 17:21:03
【问题描述】:

我正在尝试获取只有活跃爱好且角色类型为“A”的员工的列表。

我尝试使用以下查询,但没有成功。

我做错了什么?

// Get all the employees with active hobbies and have a role of 'A'
var employees = people.find(item => item.key === 'Employees').employees.map(emp => emp.hobbies).filter(hobby => hobby.filter(h => h.active === true && h.roles.includes('A')));

console.log(employees);
<script>
  var people = [{
    key: 'Employees',
    employees: [{
        name: 'joe',
        age: 20,
        hobbies: [{
          'active': true,
          name: 'skating',
          roles: ['C', 'A']
        }]
      },
      {
        name: 'amy',
        age: 32,
        hobbies: [{
          'active': true,
          name: 'surfing',
          roles: ['A']
        }]
      },
      {
        name: 'kate',
        age: 34,
        hobbies: [{
          'active': true,
          name: 'running',
          roles: ['C']
        }, {
          name: 'Chess',
          active: false,
          roles: ['C', 'A']
        }]
      }
    ]
  }];
</script>

更新

当我向数组中添加更多具有新爱好的员工时,接受的答案无法产生正确的输出。为什么会这样?

var people = [{
        key: 'Employees',
        employees: [{
                name: 'Steve',
                age: 50,
                hobbies: [{
                        active: true,
                        name: 'skating',
                        roles: ['C', 'A']
                    },
                    {
                        active: false,
                        name: 'skating',
                        roles: ['C', 'A']
                    },
                    {
                        active: true,
                        name: 'snooker',
                        roles: ['C', 'A']
                    },
                    {
                        active: true,
                        name: 'darts',
                        roles: ['C', 'A']
                    }
                ]
            },{
                name: 'joe',
                age: 20,
                hobbies: [{
                        active: true,
                        name: 'skating',
                        roles: ['C', 'A']
                    }
                ]
            }, {
                name: 'amy',
                age: 32,
                hobbies: [{
                        'active': true,
                        name: 'surfing',
                        roles: ['A']
                    }
                ]
            }, {
                name: 'kate',
                age: 34,
                hobbies: [{
                        active: true,
                        name: 'running',
                        roles: ['C']
                    }, {
                        name: 'Chess',
                        active: false,
                        roles: ['C', 'A']
                    }
                ]
            }
        ]
    }
];

var employees = people.find(item => item.key === 'Employees').employees.filter(employee => employee.hobbies.every(h => h.active && h.roles.includes('A')));

【问题讨论】:

  • 只是澄清一下:“谁只有活跃的爱好”是指他们所有的爱好都必须是活跃的?或者至少一个? “谁的角色是A型”意味着他们获得了一个角色?或者他们的积极爱好必须扮演这个角色?还是他们所有的爱好都必须扮演这个角色?

标签: javascript arrays dictionary filter


【解决方案1】:

如果您将员工映射到他们的爱好,就会出现问题:这将使您的最终结果包含爱好,而不是员工。

你需要坚持员工级别:

var people = [{key: 'Employees',employees: [{ name: 'joe', age: 20, hobbies: [{'active': true, name: 'skating', roles: ['C', 'A'] }] },{ name: 'amy', age: 32, hobbies: [{'active': true, name: 'surfing', roles: ['A'] }] }, { name: 'kate', age: 34, hobbies: [{'active': true, name: 'running', roles: ['C']}, {name: 'Chess', active: false, roles: ['C','A']}] }]}];

var employees = people.find(item => item.key === 'Employees').employees
    .filter(employee => employee.hobbies.every(h => h.active && h.roles.includes('A')));
        
console.log(employees);

在表达式中,不需要将布尔属性与true 进行比较。只需使用该属性(在本例中为active)。

如果要求员工至少有一个这样的爱好,而不是要求所有他们的爱好都符合条件,则使用 .some 而不是 .every .

【讨论】:

  • 您已经给出了非常详细的答案并回答了我的问题。谢谢
  • 我刚刚再次更新了我的问题,当我向数组中添加更多项目时,您提交的代码似乎没有产生预期的结果。请参阅上面的编辑。谢谢
  • 对于该数据,返回 3 名员工。凯特不在其中,因为并非她的每个爱好都被标记为活跃。我只能重复我回答的最后一段,因为您的问题模棱两可,您正在寻找两种逻辑中的哪一种。另请参阅 Jonas 对您的问题发表的评论,但您没有回答。我相信我的回答是正确的。您只需要根据您的期望选择.every.some
【解决方案2】:

.map(emp =&gt; emp.hobbies) 返回一个爱好数组,因此employees 的值将是过滤后的爱好列表,而不是拥有这些爱好的员工。您需要过滤员工,而不是映射他们。

// Get all the employees with active hobbies and have a role of 'A'
var employees = people.find(item => item.key === 'Employees').employees.filter(emp =>
  emp.hobbies.every(h => h.active && h.roles.includes('A')));

console.log(employees);
<script>
  var people = [{
    key: 'Employees',
    employees: [{
        name: 'joe',
        age: 20,
        hobbies: [{
          'active': true,
          name: 'skating',
          roles: ['C', 'A']
        }]
      },
      {
        name: 'amy',
        age: 32,
        hobbies: [{
          'active': true,
          name: 'surfing',
          roles: ['A']
        }]
      },
      {
        name: 'kate',
        age: 34,
        hobbies: [{
          'active': true,
          name: 'running',
          roles: ['C']
        }, {
          name: 'Chess',
          active: false,
          roles: ['C', 'A']
        }]
      }
    ]
  }];
</script>

【讨论】:

    【解决方案3】:

    您只需拨打Array.prototype.filter 即可检查您提到的条件:

    person.hobbies.every(y => y.active) && person.hobbies.every(z => z.roles.includes('A'))
    

    var people = [{
      key: 'Employees',
      employees: [{
          name: 'joe',
          age: 20,
          hobbies: [{
            'active': true,
            name: 'skating',
            roles: ['C', 'A']
          }]
        },
        {
          name: 'amy',
          age: 32,
          hobbies: [{
            'active': true,
            name: 'surfing',
            roles: ['A']
          }]
        },
        {
          name: 'kate',
          age: 34,
          hobbies: [{
            'active': true,
            name: 'running',
            roles: ['C']
          }, {
            name: 'Chess',
            active: false,
            roles: ['C', 'A']
          }]
        }
      ]
    }];
    
    let employees = people[0].employees.filter(x => 
      x.hobbies.every(y => y.active) && x.hobbies.every(z => z.roles.includes('A'))
    )
    
    console.log(employees);

    【讨论】:

      【解决方案4】:

      如果你这样做:

       .map(emp => emp.hobbies).filter(hobby =>
      

      您将每个员工映射到其爱好,结果填充为 2D 数组:

       [[ { active: true }, { active: false } ], [/*...*/]]
      

      因此hobby 不是一种爱好,而是一系列爱好。

      你说

      我正在尝试获取员工列表

      ...这意味着您实际上不想.map 去爱好,而是想.filter 员工并检查ever 爱好是否满足某些规则:

       const employees = people.find(({ key }) => key === "Employees").employees;
      
       const isActive = hobby => hobby.active && hobby.roles.includes("A");
      
       const result = employees.filter(emp => emp.hobbies.every(isActive));
      

      【讨论】:

      • 这正是我想要的,但查询没有按预期工作。我只想显示具有活跃爱好且角色为“A”的员工列表。我尝试运行此查询,但它不起作用:var result = people.find(item =&gt; item.key === 'Employees').employees.filter(emp =&gt; emp.hobbies.every(h =&gt; h.active &amp;&amp; h.roles.includes('A')))
      【解决方案5】:

      你可以使用map & filter:

      var people = [{ key: 'Employees', employees: [{ name: 'joe', age: 20, hobbies: [{ 'active': true, name: 'skating', roles: ['C', 'A'] }] }, { name: 'amy', age: 32, hobbies: [{ 'active': true, name: 'surfing', roles: ['A'] }] }, { name: 'kate', age: 34, hobbies: [{ 'active': true, name: 'running', roles: ['C'] }, { name: 'Chess', active: false, roles: ['C', 'A'] }] } ] }];
      
      const result = people.filter(x => x.key == 'Employees')
        .map(({employees}) => 
        employees.filter(x => x.hobbies.some(y => y.active && y.roles.includes('A'))))
      
      console.log(result)

      你也可以使用reduce & filter:

      var people = [{ key: 'Employees', employees: [{ name: 'joe', age: 20, hobbies: [{ 'active': true, name: 'skating', roles: ['C', 'A'] }] }, { name: 'amy', age: 32, hobbies: [{ 'active': true, name: 'surfing', roles: ['A'] }] }, { name: 'kate', age: 34, hobbies: [{ 'active': true, name: 'running', roles: ['C'] }, { name: 'Chess', active: false, roles: ['C', 'A'] }] } ] }];
      
      const result = people.filter(x => x.key == 'Employees').reduce((r,{employees}) => 
      {
        r.push(employees.filter(x => 
        x.hobbies.some(y => y.active && y.roles.includes('A'))))
        return r
      }, [])
      
      console.log(result)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-24
        • 1970-01-01
        • 1970-01-01
        • 2015-11-23
        • 2014-04-10
        • 1970-01-01
        • 2012-09-02
        相关资源
        最近更新 更多