фильтр во вложенном массиве объектов

#javascript #ecmascript-6

#javascript #ecmascript-6

Вопрос:

Я хочу иметь массив, который возвращает определенную базу свойств для проверяемого свойства, а также хочет отфильтровать уровни выбранных навыков, насколько это возможно

 const data = [
      {
        "name": "Beginner",
        "skills": [
          {
            "name": "Skill 1",
            "checked": false
          },
          {
            "name": "Skill 2",
            "checked": true
          }
        ]
      },
      {
        "name": "Intermediate",
        "skills": [
          {
            "name": "Skill 1",
            "checked": true
          },
          {
            "name": "Skill 2",
            "checked": false
          }
        ]
      },
      {
        "name": "Professional",
        "skills": [
          {
            "name": "Skill 1",
            "checked": false
          },
          {
            "name": "Skill 2",
            "checked": false
          }
        ]
      },
    ]
  

Функция возвращает проверенные навыки, но также возвращает все объекты уровня вместе с ним

 levelwithskills = data.map(level =>
              Object.assign({}, level, {
              skills: level.skills.filter(skill => skill.checked)
            })
          )
  

я ожидаю получить результат в формате

    [
      {
        "name": "Beginner",
        "skills": [
          {
            "name": "Skill 2",
            "checked": true
          }
        ]
      },
      {
        "name": "Intermediate",
        "skills": [
          {
            "name": "Skill 1",
            "checked": true
          }
        ]
      }
    ]
  

Ответ №1:

После сопоставления, filter по тому, имеет ли элемент какие-либо skills :

 const data = [{
    "name": "Beginner",
    "skills": [{
        "name": "Skill 1",
        "checked": false
      },
      {
        "name": "Skill 2",
        "checked": true
      }
    ]
  },
  {
    "name": "Intermediate",
    "skills": [{
        "name": "Skill 1",
        "checked": true
      },
      {
        "name": "Skill 2",
        "checked": false
      }
    ]
  },
  {
    "name": "Professional",
    "skills": [{
        "name": "Skill 1",
        "checked": false
      },
      {
        "name": "Skill 2",
        "checked": false
      }
    ]
  },
]
levelwithskills = data
  .map(level => ({ ...level, skills: level.skills.filter(skill => skill.checked) }))
  .filter(({ skills }) => skills.length)
console.log(levelwithskills);  

Ответ №2:

Вы можете сделать это с Array#reduce помощью метода.

 const levelwithskills = data.reduce((arr, level) => {
  // filter skills
  let skills = level.skills.filter(({ checked }) => checked);
  // check length of filtered skills if greater than 0 then push into array
  skills.length amp;amp; arr.push({ ...level, skills });
  // return array reference
  return arr
  // set initial value as an empty array for the result
}, [])
  

 const data = [{
    "name": "Beginner",
    "skills": [{
        "name": "Skill 1",
        "checked": false
      },
      {
        "name": "Skill 2",
        "checked": true
      }
    ]
  },
  {
    "name": "Intermediate",
    "skills": [{
        "name": "Skill 1",
        "checked": true
      },
      {
        "name": "Skill 2",
        "checked": false
      }
    ]
  },
  {
    "name": "Professional",
    "skills": [{
        "name": "Skill 1",
        "checked": false
      },
      {
        "name": "Skill 2",
        "checked": false
      }
    ]
  },
];

const levelwithskills = data.reduce((arr, level) => {
  let skills = level.skills.filter(({ checked }) => checked);
  skills.length amp;amp; arr.push({ ...level, skills });
  return arr
}, [])

console.log(levelwithskills)  

Ответ №3:

 const data = [
      {
        "name": "Beginner",
        "skills": [
          {
            "name": "Skill 1",
            "checked": false
          },
          {
            "name": "Skill 2",
            "checked": true
          }
        ]
      },
      {
        "name": "Intermediate",
        "skills": [
          {
            "name": "Skill 1",
            "checked": true
          },
          {
            "name": "Skill 2",
            "checked": false
          }
        ]
      },
      {
        "name": "Professional",
        "skills": [
          {
            "name": "Skill 1",
            "checked": false
          },
          {
            "name": "Skill 2",
            "checked": false
          }
        ]
      },
    ]
    
    let newData = data.map(d=>({
      ...d,
      skills: d.skills.filter(fd=>fd.checked)
    })).filter(afd=>afd.skills.length)
    console.log(newData);  

Ответ №4:

Кроме того, мы можем сделать это как

 const data = [
      {
        "name": "Beginner",
        "skills": [
          {
            "name": "Skill 1",
            "checked": false
          },
          {
            "name": "Skill 2",
            "checked": true
          }
        ]
      },
      {
        "name": "Intermediate",
        "skills": [
          {
            "name": "Skill 1",
            "checked": true
          },
          {
            "name": "Skill 2",
            "checked": false
          }
        ]
      },
      {
        "name": "Professional",
        "skills": [
          {
            "name": "Skill 1",
            "checked": false
          },
          {
            "name": "Skill 2",
            "checked": false
          }
        ]
      },
    ]




let filteredData=[]
data.map((obj)=>{
  obj.skills.map((innerObj)=>{
      if(innerObj.checked===true){
  filteredData.push({name:obj.name,
                  skills:innerObj})
      } 
  })
})
 

  console.log(filteredData)