我平均每周处理 JSON 数据 18 次,而且我几乎每次都需要在 Google 搜索处理数据的方法。能不能有一份总是可以提供答案的完全指南呢?

在本文中,我将分享在 JavaScript 中使用对象数组的基础知识。

如果你曾经使用过 JSON 结构,那么你就已经使用过 JavaScript 对象。JSON 的意思是 JavaScript Object Notation(JavaScript 对象表示法)。

创建对象是如此简单:

{
  "color": "purple",
  "type": "minivan",
  "registration": new Date('2012-02-03'),
  "capacity": 7
}

这个对象代表一辆汽车。汽车可以有多种类型和颜色,每个对象代表一辆特定的汽车。

purple

大多数时候你都是从外部服务获取此类数据。但是,有时你需要手动创建对象及其数组,就像我创建这个电子商店时所做的一样:

categories

每个类别列表项在 HTML 中看起来是像这样:

code

我不想将此代码重复 12 次,这将使其无法维护。

创建一个对象数组

我们回到汽车。看一下这一组汽车:

cars

我们可以将它们写成这样的数组:

let cars = [
  {
    "color": "purple",
    "type": "minivan",
    "registration": new Date('2017-01-03'),
    "capacity": 7
  },
  {
    "color": "red",
    "type": "station wagon",
    "registration": new Date('2018-03-03'),
    "capacity": 5
  },
  {
    ...
  },
  ...
]

对象数组并非始终保持不变。我们几乎总是需要操作它们。因此,让我们看一下如何将对象添加到已经存在的数组中。

使用 Array.unshift 在开头添加一个新对象

beginning

我们可以使用 Array.unshift 在数组的开头添加一个新的对象。

let car = {
  "color": "red",
  "type": "cabrio",
  "registration": new Date('2016-05-02'),
  "capacity": 2
}
cars.unshift(car);

使用 Array.push 在结尾添加一个新对象

ending

我们可以使用 Array.push 在数组的结尾添加一个新的对象。

let car = {
 "color": "red",
 "type": "cabrio",
 "registration": new Date('2016-05-02'),
 "capacity": 2
}
cars.push(car);

使用 Array.splice 在中间添加一个新对象

middle

我们可以使用 Array.splice 在数组的中间添加一个新的对象。这个方法非常方便,因为它也可以删除项目。注意其参数:

Array.splice(
  {index where to start},
  {how many items to remove},
  {items to add}
);

因此,如果我们要在第五个位置添加红色的 Volkswagen Cabrio,可以这么写:

let car = {
  "color": "red",
  "type": "cabrio",
  "registration": new Date('2016-05-02'),
  "capacity": 2
}
cars.splice(4, 0, car);

遍历对象数组

让我在这里问你一个问题:为什么要遍历对象数组?我要问的原因是,循环几乎从来不是我们用于实现目的的首选。

JavaScript 提供了许多功能,可以解决你的问题,而无需通过循环来实现。让我们来看看。

使用 Array.find 根据它的值在数组中找到对象

如果我们想找到红色的车,可以使用 Array.find

cars-colorred
let car = cars.find(car => car.color === "red");

它返回第一个匹配的元素:

console.log(car);
// output:
// {
//   color: 'red',
//   type: 'station wagon',
//   registration: 'Sat Mar 03 2018 01:00:00 GMT+0100 (GMT+01:00)',
//   capacity: 5
// }

也可以搜索多个值:

let car = cars.find(car => car.color === "red" && car.type === "cabrio");

在这种情况下,我们可以得到列表中的最后一辆车。

使用 Array.filter 从数组中获取满足一个条件的多个项目

Array.find 只返回一个对象,如果我们想获取所有红色的车,则需要使用 Array.filter

cars-colorred2
let redCars = cars.filter(car => car.color === "red");
console.log(redCars);
// output:
// [
//   {
//     color: 'red',
//     type: 'station wagon',
//     registration: 'Sat Mar 03 2018 01:00:00 GMT+0100 (GMT+01:00)',
//     capacity: 5
//   },
//   {
//     color: 'red',
//     type: 'cabrio',
//     registration: 'Sat Mar 03 2012 01:00:00 GMT+0100 (GMT+01:00)',
//     capacity: 2
//   }
// ]

使用 Array.map 转换一个数组的对象

我们会经常需要这么做,使用 Array.map 将一个对象数组转换为不同对象的数组。假设我们要根据汽车的大小将其分为三类。

cars-sizes
let sizes = cars.map(car => {
  if (car.capacity <= 3){
    return "small";
  }
  if (car.capacity <= 5){
    return "medium";
  }
  return "large";
});
console.log(sizes);
// output:
// ['large','medium','medium', ..., 'small']

如果我们需要更多值,也可以创建一个新的对象:

let carsProperties = cars.map(car => {
 let properties = {
   "capacity": car.capacity,
   "size": "large"
 };
 if (car.capacity <= 5){
   properties['size'] = "medium";
 }
 if (car.capacity <= 3){
   properties['size'] = "small";
 }
 return properties;
});
console.log(carsProperties);
// output:
// [
//   { capacity: 7, size: 'large' },
//   { capacity: 5, size: 'medium' },
//   { capacity: 5, size: 'medium' },
//   { capacity: 2, size: 'small' },
//   ...
// ]

使用 Array.forEach 给数组中的每一个对象添加一个属性

但是,如果我们也想要汽车对象怎么办?在这种情况下,我们可以增强对象,让它具有新的属性 size。 这是使用 Array.forEach 的一个很好的示例。

cars.forEach(car => {
 car['size'] = "large";
 if (car.capacity <= 5){
   car['size'] = "medium";
 }
 if (car.capacity <= 3){
   car['size'] = "small";
 }
});

使用 Array.sort 根据一个属性对数组进行排序

完成对象转换后,通常需要以一种方式对它们进行排序。

通常,排序是基于每个对象都具有的属性的值。我们可以使用 Array.sort,但是我们需要提供一个定义排序机制的函数。

假设我们要根据汽车载客量对汽车进行降序排序。

cars-sort
let sortedCars = cars.sort((c1, c2) => (c1.capacity < c2.capacity) ? 1 : (c1.capacity > c2.capacity) ? -1 : 0);
console.log(sortedCars);
// output:
// [
//   {
//     color: 'purple',
//     type: 'minivan',
//     registration: 'Wed Feb 01 2017 00:00:00 GMT+0100 (GMT+01:00)',
//     capacity: 7
//   },
//   {
//     color: 'red',
//     type: 'station wagon',
//     registration: 'Sat Mar 03 2018 01:00:00 GMT+0100 (GMT+01:00)',
//     capacity: 5
//   },
//   ...
// ]

Array.sort 比较两个对象,如果排序函数的结果为正,则将第一个对象放在第二位。 你可以把排序函数理解成一个问题:应该将第一个对象放在第二位吗?

sort

当两个对象的比较值相同时,请添加结果为零的情况,以避免不必要的交换。

使用 Array.every, Array.includes 检查数组中的对象是否满足条件

当我们只需要检查对象的特定条件时,Array.everyArray.some 就派上用场了。

汽车列表中有红色敞篷车吗?所有的汽车都能载至少 4 人吗?或者更细致:购物车中是否有特定产品?

cars.some(car => car.color === "red" && car.type === "cabrio");
// output: true

cars.every(car => car.capacity >= 4);
// output: false

你可能还记得 Array.includes,它类似于 Array.some,但仅适用于基本类型。

小结

在本文中,我们介绍了一些基本方法,这些方法可以帮助你创建、操作、转换和循环对象数组。它们应涵盖你会遇到的大多数情况。

如果你需要使用更高级的功能,可以看一下这个对数组的详细指南,或者联系我,我会写更多相关文章。

原文:JavaScript Array of Objects Tutorial – How to Create, Update, and Loop Through Objects Using JS Array Methods,作者:Ondrej Polesny