【问题标题】:Loop through an object and get all the values of the keys遍历一个对象并获取所有键的值
【发布时间】:2021-04-29 21:24:16
【问题描述】:

我正在尝试遍历一个对象并获取 name 的所有键值,我正在通过以下方式进行操作:

var fakeData = {
     "manufacturer": "tesla",
     "cars": [
          {"title": "CALI", "name": "CALI", "type": "string" },
          {"title": "TEXAS", "name": "TEXAS", "type": "string" },
          {"title": "NY", "name": "NY", "type": "string" }
     ],
     "usedCars": [
          {"title": "FL", "name": "FL", "type": "string" }
     ],
}

returnName(fakeData) {
    for (key in fakeData.cars && fakeData.usedCars) {
     //return name property  of cars and usedCars arrays.
     //fakeData is the representation of the req.body data that might 
     //sometimes not necessarily have either cars or usedCars

    }

}

如果我这样做,它会返回 undefined。有什么方法可以在一个 for 循环中满足这些条件并获得所需的结果?

【问题讨论】:

  • 您能解释一下“获取名称的所有键值”是什么意思吗?您的意思是要从汽车和二手车中获取名称值的列表吗?
  • 是的,这是正确的,所以应该是 CALI, TEXAS, NY, FL @sofa_maniac
  • 注意,cars 和 usedCars 是数组,不是对象
  • 假设carsusedCars 永远不会未定义,简单的[...fakeData.cars, ...fakeData.usedCars].map(car => car.title)
  • 如果可以是undefined,那么就使用[...(fakeData.cars || []), ...(fakeData.usedCars || [])].map(car => car.title)

标签: javascript arrays for-loop ecmascript-6


【解决方案1】:

这样就可以了。

(fakeData.cars?fakeData.cars:[]).concat(fakeData.usedCars?fakeData.usedCars:[]).map(car => car.name)

输出:

["CALI", "TEXAS", "NY", "FL"]

解释:

首先,我们使用条件来检查 faekData.cars 是否确实存在。如果是,请获取数组。如果不是,则在其位置返回一个空数组。

  (fakeData.cars)?fakeData.cars:[]

这转换为:(条件==真)? (如果为真,请执行此操作):(如果为假,请执行此操作)

如果数组不存在,则不满足条件。所以,“(do this if false)”部分将被执行。

然后,我们对第二个数组执行相同的操作。通过使用“concat”,我们将两个数组连接成一个数组。然后,我们使用“map”将整个对象转换为“name”属性的值。

【讨论】:

  • 效果很好。你能解释一下这里发生了什么吗? @sofa_maniac
  • 更新了答案。
  • 我认为您发布的上一个答案效果很好,因为这个返回 [Object object] @sofa_maniac
  • fakeData.cars.concat(fakeData.usedCars?fakeData.usedCars:[]).map(car => car.name);
  • 这很好用:(fakeData.cars?fakeData.cars:[]).concat(fakeData.usedCars?fakeData.usedCars:[]).map(car => car.name).join (', ')
【解决方案2】:

希望这就是你要找的。​​p>

var fakeData = {
     "manufacturer": "tesla",
     "cars": [
          {"title": "CALI", "name": "CALI", "type": "string" },
          {"title": "TEXAS", "name": "TEXAS", "type": "string" },
          {"title": "NY", "name": "NY", "type": "string" }
     ],
     "usedCars": [
          {"title": "FL", "name": "FL", "type": "string" }
     ],
};

[].concat(
    fakeData.cars ? fakeData.cars : [],
    fakeData.usedCars ? fakeData.usedCars : [],
    fakeData.undefinedCars ? fakeData.undefinedCars : [],
).forEach(car => {
    console.log(car.name);
});

对于更多数组,只需将它们添加到.concat() 函数中,用逗号分隔:

array1.concat(array2, array3, array4)

【讨论】:

  • 感谢您的回答,但如果 usedCars 数组或 cars 数组中的任何一个丢失,这将不起作用,并且会抛出错误消息 Cannot read name of undefined。除了使用可选链接之外,还有其他方法可以使这项工作吗?
  • 我的新编辑应该已经为您实现了这一点。
  • 请注意,在我将分号 ; 添加到 fakeData 对象的末尾之前,最新的编辑不起作用。
【解决方案3】:

for (key in fakeData.cars && fakeData.usedCars) 的意思不是“把汽车和二手车的钥匙给我”,它的意思是“给我汽车和二手车的评估钥匙”(这是汽车,因为它是真实的)。

相反,只需使用 .map 并获取名称:

var fakeData = {
     "manufacturer": "tesla",
     "cars": [
          {"title": "CALI", "name": "CALI", "type": "string" },
          {"title": "TEXAS", "name": "TEXAS", "type": "string" },
          {"title": "NY", "name": "NY", "type": "string" }
     ],
     "usedCars": [
          {"title": "FL", "name": "FL", "type": "string" }
     ],
}

/*
This doesn't mean "get me the keys in cars and usedCars"
it means "get me the keys of the evaluation of cars && usedCars"
(which is cars since it's truthy)
returnName(fakeData) {
    for (key in fakeData.cars && fakeData.usedCars) {
     //return name property  of cars and usedCars arrays.
     //fakeData is the representation of the req.body data that might 
     //sometimes not necessarily have either cars or usedCars

    }

}
*/

// You can just map the arrays and spread them into a new array:
// If you have to deal with certain properties not being there,
// you can use optional chaining, the ? and ?? [] pieces
const names = [
  ...fakeData?.cars?.map(({name}) => name) ?? [],
  ...fakeData?.usedCars?.map(({name}) => name) ?? []
];

console.log(names); // ["CALI", "TEXAS", "NY", "FL"]

【讨论】:

  • 太棒了,感谢您的解释。如果请求正文中缺少 usedCars,这将不起作用。它抛出一个错误说TypeError: Cannot read property 'map' of undefined@zero298
  • @boomchickawawa 如果您必须处理某些不存在的属性,您可以使用可选链。
  • 是的,这完全有道理,但以前的节点版本不支持它,所以有没有可选链接的替代方法? @zero298
【解决方案4】:

这应该打印所有的车名

var fakeData = {
     "manufacturer": "tesla",
     "cars": [
          {"title": "CALI", "name": "CALI", "type": "string" },
          {"title": "TEXAS", "name": "TEXAS", "type": "string" },
          {"title": "NY", "name": "NY", "type": "string" }
     ],
     "usedCars": [
          {"title": "FL", "name": "FL", "type": "string" }
     ],
}

var results = [];

function returnNames(){
    for(index in fakeData.cars){
        results.push(fakeData.cars[index].title);
    }
    for(index in fakeData.usedCars){
        results.push(fakeData.usedCars[index].title);
    }
    
    console.log("car names: " + results)
}

【讨论】:

  • 我认为使用两个 for 循环会有点矫枉过正,但感谢您的回答
【解决方案5】:

您可以将您想要的对象连接到一个数组中,并映射出您想要访问的任何值。这就是你要找的吗?

const fakeData = {
    manufacturer: 'tesla',
    cars: [
      { title: 'CALI', name: 'CALI', type: 'string' },
      { title: 'TEXAS', name: 'TEXAS', type: 'string' },
      { title: 'NY', name: 'NY', type: 'string' }
    ],
    usedCars: [{ title: 'FL', name: 'FL', type: 'string' }]
  };
  
  const combinedCarData = [...fakeData.cars, ...fakeData.usedCars];
  
  // Map whatever values you would like to access
  
  combinedCarData.map(car => {
    console.log(car.title);
    console.log(car.name);
    console.log(car.type);
  });

【讨论】:

    猜你喜欢
    • 2017-06-07
    • 2019-01-12
    • 1970-01-01
    • 2017-07-18
    • 1970-01-01
    • 1970-01-01
    • 2017-12-28
    • 1970-01-01
    • 2017-03-02
    相关资源
    最近更新 更多