开发者问题收集

如何搜索两个对象属性

2022-05-22
117

我是新手程序员,目前正在学习 JavaScript。我试图运行 Object.keys() 代码来返回用户对象中人员的“技能”,并根据结果查找谁拥有更多技能。当我运行代码时,我不断收到“未捕获 TypeError:无法读取未定义的属性(读取“技能”)”。我不知道如何在不单独搜索每个用户的情况下访问技能键的值。这是我正在使用的代码:

const users = {
    Alex: {
      email: '[email protected]',
      skills: ['HTML', 'CSS', 'JavaScript'],
      age: 20,
      isLoggedIn: false,
      points: 30
    },
    Asab: {
      email: '[email protected]',
      skills: ['HTML', 'CSS', 'JavaScript', 'Redux', 'MongoDB', 'Express', 'React', 
      'Node'],
      age: 25,
      isLoggedIn: false,
      points: 50
    },
}
const names = Object.keys(users)
const userSkills = Object.keys(users.names.skills)
console.log(userSkills)

//The above doesn't work, however this does:
const alexSkills = Object.keys(users.Alex.skills)
console.log(alexSkills) //3
const asabSkills = Object.keys(users.Asab.skills)
console.log(asabSkills) //8

(console.log(Object.keys(users.Alex.Skills))
//alternate format I've used, but I'm asked to do the former.)

有没有一种方法可以访问和显示技能键,而不必单独搜索每个属性来找到它们?我知道我会通过单独搜索得到答案,但对具有大量属性的对象执行此操作将花费太长时间,我想学习一种更快的方法。任何帮助都值得感激!

2个回答

有很多方法可以做到这一点,让我们使用 Object.keys 和一个 for 循环来实现它

const keys = Object.keys(users);
for(let i=0; i<keys.length; i++){
  let user = keys[i]; //Alex or Asab
  let skills = users[user].skills;
  let skill_count = skills.length;
  console.log(`${user} has ${skill_count} skills.`)
}
Enes Can Güneş
2022-05-22

您需要谨慎使用键,以及如何使用从 Object.keys 返回的值(它将是一个数组)。

如果您只是遍历每个用户的每个技能列表,那么算法的时间复杂度将为 O(m*n),其中 m 表示用户数量, n 表示每个用户的技能数量。

如果您想使搜索技能更有效率,您可以保持技能列表排序,然后使用搜索算法来查找技能。

const users = {
    Alex: {
      email: '[email protected]',
      skills: ['HTML', 'CSS', 'JavaScript'],
      age: 20,
      isLoggedIn: false,
      points: 30
    },
    Asab: {
      email: '[email protected]',
      skills: ['HTML', 'CSS', 'JavaScript', 'Redux', 'MongoDB', 'Express', 'React', 
      'Node'],
      age: 25,
      isLoggedIn: false,
      points: 50
    },
}

const names = Object.keys(users)
console.log(names) // 'Alex', 'Asab'

const userSkills = users[names[0]].skills.join(', ')
console.log(userSkills) // 'HTML, CSS, JavaScript'

function getUserSkills(user) {
  return users[user].skills.join(', ')
}
console.log(getUserSkills('Alex')) // 'HTML, CSS, JavaScript'

function usersWithSkill(users, skill) {
  const userNames = Object.keys(users)
  const result = []
  
  for(let x = 0; x < userNames.length; x++) {
    const currentUser = users[userNames[x]]
    const currentUserSkills = currentUser.skills

    for(let y = 0; y < currentUserSkills.length; y++) {
      if(currentUserSkills[y] === skill) {
        result.push(userNames[x])
        break
      }
    }
  }
  
  return result.length ? result.join(', ') : 'Skill not found'
}

console.log(usersWithSkill(users, 'CSS')) // 'Alex, Asab'
console.log(usersWithSkill(users, 'MongoDB')) // 'Asab'
console.log(usersWithSkill(users, 'C')) // 'Skill not found'
Ben Aston
2022-05-22