【问题标题】:Accessing objects访问对象
【发布时间】:2019-04-23 15:21:57
【问题描述】:

我写了一个简单的函数来访问下面数组中的一些值,并且嵌套在数组中的是多个对象。

我的问题与我的 2 个循环有关。我知道我必须首先遍历数组才能访问 3 个对象,但为什么我必须遍历 3 个对象才能访问这些值?

基本上为什么我不能运行初始 for 循环并通过这样做来访问声音:

animalNoises[i][animal][country]

以上对我来说返回未定义。它与每 3 个动物对象的结构方式有关吗?

感谢您的帮助。我非常感谢堆栈溢出社区的持续帮助。

function petSounds(animal, country) {
let phrase = ''
for (let i = 0; i < animalNoises.length; i++) {
  for (let key in animalNoises[i]){
    if (animal === key){
      let sound = animalNoises[i][key][country];
      phrase = animal + 's' + ' in ' + country + ' say ' + sound
      }
    }
  }
 return phrase
}

    let animalNoises = [
  { 'dog': {
    'America' : 'Woof! Woof!',
    'Germany' : 'Wau Wau!',
    'England' : 'Bow wow!',
    'Uruguay' : 'Jua jua!',
    'Afrikaans' : 'Blaf!',
    'Korea' : 'Mong mong!',
    'Iceland' : 'Voff voff!',
    'Albania' : 'Ham!',
    'Algeria' : 'Ouaf ouaf!'
    }
  },
  { 'cat': {
    'America' : 'Meow',
    'Germany' : 'Miauw!',
    'England' : 'mew mew',
    'Uruguay' : 'Miau Miau!',
    'Afrikaans' : 'Purr',
    'Korea' : 'Nyaong!',
    'Iceland' : 'Kurnau!',
    'Albania' : 'Miau',
    'Algeria' : 'Miaou!'
    }
  },
  { 'chicken': {
    'America' : 'Cluck cluck',
    'Germany' : 'tock tock tock',
    'England' : 'Cluck Cluck',
    'Uruguay' : 'gut gut gdak',
    'Afrikaans' : 'kukeleku',
    'Korea' : 'ko-ko-ko',
    'Iceland' : 'Chuck-chuck!',
    'Albania' : 'Kotkot',
    'Algeria' : 'Cotcotcodet'
    }
  }
];

【问题讨论】:

  • 适用于console.log(petSounds('dog', 'America')); -> dogs in America say Woof! Woof!console.log(petSounds('chicken', 'Algeria')); -> chickens in Algeria say Cotcotcodet
  • 代码看起来没问题。可能是您使用不属于对象键的参数调用它,因此它返回未定义。
  • 另外,你明白这样你会在所有循环结束时得到一个返回值。
  • 如果把结构改成更合理的{'dog': {...}, 'cat': {...}, 'chicken': {...}},就可以做到animalSounds[animal][country],零循环。

标签: javascript arrays javascript-objects for-in-loop


【解决方案1】:

如果您想保留现在的表单,您可以随时使用Array#find(),然后使用in 运算符检查,然后使用模板文字,您可以轻松创建字符串。

function petSounds(animal, country) {
 const noise = animalNoises.find(obj => animal in obj)[animal][country];
 return `${animal}s in ${country} say ${noise}`
}

    let animalNoises = [
  { 'dog': {
    'America' : 'Woof! Woof!',
    'Germany' : 'Wau Wau!',
    'England' : 'Bow wow!',
    'Uruguay' : 'Jua jua!',
    'Afrikaans' : 'Blaf!',
    'Korea' : 'Mong mong!',
    'Iceland' : 'Voff voff!',
    'Albania' : 'Ham!',
    'Algeria' : 'Ouaf ouaf!'
    }
  },
  { 'cat': {
    'America' : 'Meow',
    'Germany' : 'Miauw!',
    'England' : 'mew mew',
    'Uruguay' : 'Miau Miau!',
    'Afrikaans' : 'Purr',
    'Korea' : 'Nyaong!',
    'Iceland' : 'Kurnau!',
    'Albania' : 'Miau',
    'Algeria' : 'Miaou!'
    }
  },
  { 'chicken': {
    'America' : 'Cluck cluck',
    'Germany' : 'tock tock tock',
    'England' : 'Cluck Cluck',
    'Uruguay' : 'gut gut gdak',
    'Afrikaans' : 'kukeleku',
    'Korea' : 'ko-ko-ko',
    'Iceland' : 'Chuck-chuck!',
    'Albania' : 'Kotkot',
    'Algeria' : 'Cotcotcodet'
    }
  }
];

否则,您的版本会在循环时循环,而您只需检查是否存在即可。

当然给猫剥皮的方法有很多种,所以上面的等价于

function petSounds(animal, country) {
 const noise = animalNoises.find(obj => obj.hasOwnProperty(animal))[animal][country];
 return `${animal}s in ${country} say ${noise}`
}

当然,如果您从其他地方接收此 JSON,您可以对其进行缩减,然后将键和值关联到一个超级对象中(使用 Array#reduce()Object.entries()

animalNoises = animalNoise.reduce((acc, obj) => {
  Object.entries(obj).forEach(([key, value]) => {
   acc[key] = value;
  });
  return acc;
 },
 {}
)

function petSounds(animal, country) {
  return `${animal}s in ${country} say ${animalNoises[animal][country]}`;
}

如果您想了解更多关于可以使用 Arrays 做的很酷的事情,您应该查看MDN for JavaScript Arrays

The in operator 是缩短Object#hasOwnProperty() 的一种非常有用的方法

And as always a lot more information about JavaScript can be found at the MDN


Object Sestructuring 的一些额外乐趣只是另一种安排事情的方式:

function petSounds(animal, country) {
 const { [animal]: { [country]: noise } } = animalNoises.find(obj => animal in obj);
 return `${animal}s in ${country} say ${noise}`
}

【讨论】:

    【解决方案2】:

    您的解决方案有效,只有一个 for 循环。您错过了指定单引号。 当我简单地控制它时,它会返回特定的值。

    animalNoises[0]['dog']['Korea']
    "Mong mong!"
    

    在循环中,您需要通过指定键名和国家/地区值从数组中访问。

    这与每 3 个动物对象的结构方式无关

    当我调用你的函数时,它运行良好。

    petSounds('dog', 'Korea')
    "dogs in Korea say Mong mong!"
    

    或者你可以修改你的函数如下,它执行相同的减少内循环:

    function petSounds(animal, country) {
    let phrase = ''
      for (let i = 0; i < animalNoises.length; i++) {
        let key = Object.keys(animalNoises[i])[0];
        if (animal === key){
          let sound = animalNoises[i][key][country];
          phrase = animal + 's' + ' in ' + country + ' say ' + sound
        }
      }
      return phrase
    }
    

    【讨论】:

    • 我认为他的第二个 for 循环是检查动物的有效性?这样它就可以在尝试将其连接到他的返回值之前确保密钥存在
    • 第二个循环不是必需的。您可以通过 Object.keys(animalNoises[i])[0] 取键名与动物进行比较
    • 我认为你错过了我所说的。其他人已经建议可能更改 JSON 的格式,但是如果 JSON 是从外部源提供的并且您的对象有额外的键怎么办?另外,如果有一个原型属性等于您发送的密钥怎么办?他的第二个循环是检查以确保该对象具有它自己的动物属性。
    • 在这种情况下,需要第二个循环。但我认为他在他的问题中要问的是:为什么我必须遍历 3 个对象才能访问这些值?因此,根据他的问题,他可以在不循环的情况下访问这些值。但如果对象有额外的键,那么我同意你的评论。
    【解决方案3】:

    您需要更新您的 json 以简化功能(使用以动物类型为键的对象):

    function petSounds(animal, country) {
      const sound = animalNoises[animal][country];
      const phrase = animal + 's' + ' in ' + country + ' say ' + sound;
      return phrase;
    }
    
    let animalNoises = {
      'dog': {
        'America': 'Woof! Woof!',
        'Germany': 'Wau Wau!',
        'England': 'Bow wow!',
        'Uruguay': 'Jua jua!',
        'Afrikaans': 'Blaf!',
        'Korea': 'Mong mong!',
        'Iceland': 'Voff voff!',
        'Albania': 'Ham!',
        'Algeria': 'Ouaf ouaf!'
    
      },
      'cat': {
        'America': 'Meow',
        'Germany': 'Miauw!',
        'England': 'mew mew',
        'Uruguay': 'Miau Miau!',
        'Afrikaans': 'Purr',
        'Korea': 'Nyaong!',
        'Iceland': 'Kurnau!',
        'Albania': 'Miau',
        'Algeria': 'Miaou!'
      },
      'chicken': {
        'America': 'Cluck cluck',
        'Germany': 'tock tock tock',
        'England': 'Cluck Cluck',
        'Uruguay': 'gut gut gdak',
        'Afrikaans': 'kukeleku',
        'Korea': 'ko-ko-ko',
        'Iceland': 'Chuck-chuck!',
        'Albania': 'Kotkot',
        'Algeria': 'Cotcotcodet'
      }
    };
    
    console.log(petSounds('cat', 'America'));
    console.log(petSounds('dog', 'Iceland'));
    console.log(petSounds('chicken', 'Germany'));

    【讨论】:

      猜你喜欢
      • 2021-11-23
      • 1970-01-01
      • 2020-12-09
      • 2016-01-31
      • 2013-01-12
      • 2016-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多