过滤器数组存在于对象数组中而​​不影响主数组

Posted

技术标签:

【中文标题】过滤器数组存在于对象数组中而​​不影响主数组【英文标题】:Filter array present inside a array of objects without affecting the main array 【发布时间】:2020-09-11 18:47:21 【问题描述】:

我有下面这样的 JSON,我需要过滤掉年龄小于 25 岁的工人。

var employee = 
  "value": [
    
      "position": "Seniro Developer",
      "description": "Developemwnt",
      "workers": [
        
          "name": "Kumar",
          "age": 22
        ,
        
          "name": "aravinth",
          "age": 29
        ,
        
          "name": "sathish",
          "age": 35
        
      ]
    ,
    
      "position": "Tester",
      "description": "testing",
      "workers": [
        
          "name": "vinth",
          "age": 18
        ,
        
          "name": "rahul",
          "age": 45
        ,
        
          "name": "sathish",
          "age": 12
        
      ]
    
  ]

我尝试使用下面的代码,但它返回了工人数组中的所有值,但我的期望是它应该只返回 25 岁以上的员工。

如果我使用 Map 功能,它也会影响员工对象。

var filteredResult = employee.filter(e => e.workers.some(w => w.age < 25))

预期结果:


  "value": [
    
      "position": "Seniro Developer",
      "description": "Developemwnt",
      "workers": [
        
          "name": "Kumar",
          "age": 22
        
      ]
    ,
    
      "position": "Tester",
      "description": "testing",
      "workers": [
        
          "name": "vinth",
          "age": 18
        ,
        
          "name": "sathish",
          "age": 12
        
      ]
    
  ]

【问题讨论】:

【参考方案1】:

你可以用一个map和一个filter来做,为了避免修改原始数组,你可以使用Object.asign

var employee = 
  "value": [
      "position": "Seniro Developer",
      "description": "Developemwnt",
      "workers": [
          "name": "Kumar",
          "age": 22
        ,
        
          "name": "aravinth",
          "age": 29
        ,
        
          "name": "sathish",
          "age": 35
        
      ]
    ,
    
      "position": "Tester",
      "description": "testing",
      "workers": [
          "name": "vinth",
          "age": 18
        ,
        
          "name": "rahul",
          "age": 45
        ,
        
          "name": "sathish",
          "age": 12
        
      ]
    
  ]




var filteredResult = employee.value.map(e => 
  let filter = e.workers.filter(w => w.age < 25)
  
  return Object.assign(, e, workers: filter)
)

console.log('original', employee)
console.log('result', filteredResult)

【讨论】:

对此我有一个疑问,Object.assign 将创建一个新对象,它不是与主对象的引用对吗?如果是,有没有办法从主对象创建引用而不是创建新对象。【参考方案2】:

您可以减少数组并检查过滤后的workers 是否有一些元素,然后将更改了workers 的新对象推送到结果集中。

var employee =  value: [ position: "Seniro Developer", description: "Developemwnt", workers: [ name: "Kumar", age: 22 ,  name: "aravinth", age: 29 ,  name: "sathish", age: 35 ] ,  position: "Tester", description: "testing", workers: [ name: "vinth", age: 18 ,  name: "rahul", age: 45 ,  name: "sathish", age: 12 ] ] ,
    value = employee.value.reduce((r, o) => 
        const workers = o.workers.filter(( age ) => age < 25);
        if (workers.length) r.push( ...o, workers );
        return r;
    , []),
    result =  value ;

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

【讨论】:

【参考方案3】:

你也可以试试这个:

var employee =  "value": [  "position": "Seniro Developer", "description": "Developemwnt", "workers": [  "name": "Kumar", "age": 22 ,  "name": "aravinth", "age": 29 ,  "name": "sathish", "age": 35  ] ,  "position": "Tester", "description": "testing", "workers": [  "name": "vinth", "age": 18 ,  "name": "rahul", "age": 45 ,  "name": "sathish", "age": 12  ]  ]
result = employee.value.map((workers, ...rest)=>(...rest, workers:[...workers.filter(k=>k.age<25)]));

console.log(result);

【讨论】:

对此我有一个疑问,Object.assign 将创建一个新对象,它不是与主对象的引用对吗?如果是,有没有办法从主对象创建引用而不是创建新对象【参考方案4】:

使用 map 并在返回对象中创建 workers 键时使用 filter 获取年龄小于 25 岁的员工。map 将创建一个数组

var employee = 
  "value": [
      "position": "Seniro Developer",
      "description": "Developemwnt",
      "workers": [
          "name": "Kumar",
          "age": 22
        ,
        
          "name": "aravinth",
          "age": 29
        ,
        
          "name": "sathish",
          "age": 35
        
      ]
    ,
    
      "position": "Tester",
      "description": "testing",
      "workers": [
          "name": "vinth",
          "age": 18
        ,
        
          "name": "rahul",
          "age": 45
        ,
        
          "name": "sathish",
          "age": 12
        
      ]
    
  ]


let filteredEmployee = employee.value.map((item) => 
  return 
    "position": item.position,
    "description": item.description,
    "workers": item.workers.filter(elem => elem.age < 25)
  
);
let newObject = Object.assign(, 
  value: filteredEmployee
);

console.log(newObject)

【讨论】:

感谢您的回复。上面给出的是一个示例 JSON,除了“位置”和“描述”之外,我将在每个对象内部有很多属性,所以如何处理所有这些属性。 它们与位置和描述有何不同? 没有什么不同,但我有超过 50 个属性,我无法像上面给出的那样定义每个属性。【参考方案5】:

您可以将map 方法与... rest syntax 一起使用:

employee.value.map((workers, ...rest) => (...rest, 
    workers: workers.filter(w => w.age < 25)));

一个例子:

let employee = 
    "value": [
      
        "position": "Seniro Developer",
        "description": "Developemwnt",
        "workers": [
          
            "name": "Kumar",
            "age": 22
          ,
          
            "name": "aravinth",
            "age": 29
          ,
          
            "name": "sathish",
            "age": 35
          
        ]
      ,
      
        "position": "Tester",
        "description": "testing",
        "workers": [
          
            "name": "vinth",
            "age": 18
          ,
          
            "name": "rahul",
            "age": 45
          ,
          
            "name": "sathish",
            "age": 12
          
        ]
      
    ]
  

  const result = employee.value.map((workers, ...rest) => (...rest, workers: workers.filter(w => w.age < 25)));
  console.log(result);

【讨论】:

以上是关于过滤器数组存在于对象数组中而​​不影响主数组的主要内容,如果未能解决你的问题,请参考以下文章

检查对象值是不是存在于 Javascript 对象数组中,如果不存在则将新对象添加到数组

从过滤数组和主数组中删除相同的对象

基于单独数组中的对象过滤 NSDictionaries 数组

DAY_4-回顾,对象,数组基本概念——1

数组的filter返回新数组所以不影响原数组吗?

根据以数组形式存在于对象值内的值搜索对象数组