【ES6】day33-array-extensions

作者:mario 发布时间: 2026-08-27 阅读量:6 评论数:0

第三十三天:数组扩展 — 展开运算符与便捷查找

蜗牛往上爬 · 前端工业可视化学习笔记 第 33 篇
数组是工业数据的主战场。ES6 给数组带来了展开运算符(...)、find/findIndex、Array.from、includes、flat 等一批利器。今天学完,数据处理会又简洁又强大。


目录


一、展开运算符 …

展开(...)是把数组/对象"打散"——用于合并、复制、传参。

// ===== 合并数组 =====
const a = ["CNC-001", "AGV-002"];
const b = ["ARM-003", "CNC-004"];
const all = [...a, ...b];
// ["CNC-001", "AGV-002", "ARM-003", "CNC-004"]

// ===== 复制数组(浅拷贝)=====
const original = ["CNC-001", "AGV-002"];
const copy = [...original];
copy.push("ARM-003");
console.log(original.length);  // 2(原数组没变)

// ===== 传参 =====
const nums = [3, 1, 2];
console.log(Math.max(...nums));  // 3

// ===== 合并对象(对象展开)=====
const base = { name: "CNC-001", temp: 65 };
const ext = { ...base, status: "运行中" };
// { name: "CNC-001", temp: 65, status: "运行中" }

// 覆盖属性(后写覆盖)
const config = { ...base, temp: 85 };
// { name: "CNC-001", temp: 85 }

展开 vs 解构:展开是"打散"(合并/复制/传参),解构是"提取"(取值)。方向相反。


二、find 与 findIndex

const deviceList = [
  { id: "CNC-001", temp: 65 },
  { id: "AGV-002", temp: 42 },
  { id: "ARM-003", temp: 38 }
];

// find:返回第一个满足条件的元素
const target = deviceList.find(d => d.id === "AGV-002");
// { id: "AGV-002", temp: 42 }
// 找不到返回 undefined

// findIndex:返回下标
const index = deviceList.findIndex(d => d.temp > 50);
// 0(CNC-001);找不到返回 -1

// 应用:根据 id 查找并更新
const idToUpdate = "AGV-002";
const device = deviceList.find(d => d.id === idToUpdate);
if (device) {
  device.temp = 50;
}

对比 indexOf:indexOf 只能查"值",find 能按"条件"查(尤其是对象数组)。


三、Array.from 与 Array.of

// Array.from:类数组 → 真数组
// 场景 1:arguments
function sumAll() {
  const nums = Array.from(arguments);
  return nums.reduce((s, n) => s + n, 0);
}
console.log(sumAll(1, 2, 3));  // 6

// 场景 2:NodeList → 可用数组方法
const cards = Array.from(document.querySelectorAll(".card"));

// 场景 3:生成序列(第二参数是映射函数)
const range = Array.from({ length: 5 }, (_, i) => i + 1);
// [1, 2, 3, 4, 5]
const months = Array.from({ length: 12 }, (_, i) => i + 1);
// [1, 2, ..., 12]

// Array.of:创建数组(元素是参数)
const nums = Array.of(1, 2, 3);
// [1, 2, 3]

四、includes 与 flat

// includes(数组版):判断存在
const ids = ["CNC-001", "AGV-002"];
console.log(ids.includes("AGV-002"));  // true
console.log(ids.includes("ARM-003"));  // false

// 应用:判断是否在监控列表
const monitored = ["CNC-001", "CNC-004"];
const isMonitored = id => monitored.includes(id);
console.log(isMonitored("CNC-001"));  // true

// flat:拍平嵌套数组
const nested = [[1, 2], [3, 4]];
console.log(nested.flat());  // [1, 2, 3, 4]

const deep = [1, [2, [3, [4]]]];
console.log(deep.flat(2));          // [1, 2, 3, [4]]
console.log(deep.flat(Infinity));   // [1, 2, 3, 4]

// flatMap:拍平 + 映射(一步)
const devices = [
  { id: "A", sensors: [1, 2] },
  { id: "B", sensors: [3, 4] }
];
const allSensors = devices.flatMap(d => d.sensors);
// [1, 2, 3, 4]

五、sort 排序注意点

// ❌ 数字排序默认按字符串!结果错误
const nums = [3, 10, 1, 20];
console.log(nums.sort());  // [1, 10, 20, 3]

// ✅ 必须传比较函数
console.log(nums.sort((a, b) => a - b));  // [1, 3, 10, 20] 升序
console.log(nums.sort((a, b) => b - a));  // [20, 10, 3, 1] 降序

// 对象数组按属性排序
const deviceList = [
  { id: "CNC-001", temp: 65 },
  { id: "AGV-002", temp: 42 },
  { id: "ARM-003", temp: 38 }
];
const sorted = [...deviceList].sort((a, b) => a.temp - b.temp);
// ⭐ 用 [...arr] 复制,避免 sort 修改原数组

六、综合实战:数据统计面板

const deviceList = [
  { id: "CNC-001", temp: 65, online: true,  workshop: "一号车间" },
  { id: "AGV-002", temp: 42, online: true,  workshop: "二号车间" },
  { id: "ARM-003", temp: 38, online: false, workshop: "一号车间" },
  { id: "CNC-004", temp: 88, online: true,  workshop: "二号车间" }
];

// 在线数量
const onlineCount = deviceList.filter(d => d.online).length;  // 3

// 平均温度
const avgTemp = (
  deviceList.map(d => d.temp).reduce((s, t) => s + t, 0) /
  deviceList.length
).toFixed(1);  // "58.3"

// 各车间数量
const byWorkshop = deviceList.reduce((acc, d) => {
  acc[d.workshop] = (acc[d.workshop] || 0) + 1;
  return acc;
}, {});  // { "一号车间": 2, "二号车间": 2 }

// 高温设备(>50)
const hotIds = deviceList.filter(d => d.temp > 50).map(d => d.id);
// ["CNC-001", "CNC-004"]

// 按温度降序(复制后排序)
const byTemp = [...deviceList].sort((a, b) => b.temp - a.temp);
// CNC-004(88) → CNC-001(65) → AGV-002(42) → ARM-003(38)

// 生成统计面板 HTML(模板字符串 + map + join)
const panelHTML = `
  <div class="stat-panel">
    <div>在线:<strong>${onlineCount}</strong></div>
    <div>均温:<strong>${avgTemp}°C</strong></div>
    <div>高温:<strong>${hotIds.length}</strong></div>
    <div>车间:<strong>${Object.keys(byWorkshop).length}</strong></div>
  </div>
`;

七、总结

方法

用途

注意

... 展开

合并/复制/传参/对象展开

与解构方向相反

find

按条件查元素

找不到返回 undefined

findIndex

按条件查下标

找不到返回 -1

Array.from

类数组→真数组、生成序列

第二参是映射函数

Array.of

创建数组

includes

判断存在

比 indexOf 直观

flat / flatMap

拍平嵌套

Infinity 全拍平

sort

排序

必须传比较函数、会改原数组

🎯 数组扩展学完,数据处理的工具箱就齐全了。下周学对象扩展与 Set/Map——ES6 的数据结构升级。

评论