From 33058f2b292b3a581333bdfb21b8f671898c5060 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:40:17 -0500 Subject: initial commit --- .../reference/global_objects/array/flat/index.html | 218 +++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/flat/index.html (limited to 'files/zh-cn/web/javascript/reference/global_objects/array/flat') diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/flat/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/flat/index.html new file mode 100644 index 0000000000..5346c65b82 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/array/flat/index.html @@ -0,0 +1,218 @@ +--- +title: Array.prototype.flat() +slug: Web/JavaScript/Reference/Global_Objects/Array/flat +tags: + - JavaScript + - 原型 + - 参考 + - 数组 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Array/flat +--- +
{{JSRef}}
+ +

flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

+ +
{{EmbedInteractiveExample("pages/js/array-flat.html")}}
+ + + +

语法

+ +
var newArray = arr.flat([depth])
+ +

参数

+ +
+
depth {{optional_inline}}
+
指定要提取嵌套数组的结构深度,默认值为 1。
+
+ +

返回值

+ +

一个包含将数组与子数组中所有元素的新数组。

+ +

示例

+ +

扁平化嵌套数组

+ +
var arr1 = [1, 2, [3, 4]];
+arr1.flat();
+// [1, 2, 3, 4]
+
+var arr2 = [1, 2, [3, 4, [5, 6]]];
+arr2.flat();
+// [1, 2, 3, 4, [5, 6]]
+
+var arr3 = [1, 2, [3, 4, [5, 6]]];
+arr3.flat(2);
+// [1, 2, 3, 4, 5, 6]
+
+//使用 Infinity,可展开任意深度的嵌套数组
+var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
+arr4.flat(Infinity);
+// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ +

扁平化与数组空项

+ +

flat() 方法会移除数组中的空项:

+ +
var arr4 = [1, 2, , 4, 5];
+arr4.flat();
+// [1, 2, 4, 5]
+ +

替代方案

+ +

使用 reduceconcat

+ +
var arr = [1, 2, [3, 4]];
+
+// 展开一层数组
+arr.flat();
+// 等效于
+arr.reduce((acc, val) => acc.concat(val), []);
+// [1, 2, 3, 4]
+
+// 使用扩展运算符 ...
+const flattened = arr => [].concat(...arr);
+ +

reduce + concat + isArray + recursivity

+ +
// 使用 reduce、concat 和递归展开无限多层嵌套的数组
+var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]];
+
+function flatDeep(arr, d = 1) {
+   return d > 0 ? arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatDeep(val, d - 1) : val), [])
+                : arr.slice();
+};
+
+flatDeep(arr1, Infinity);
+// [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]
+ +

forEach+isArray+push+recursivity

+ +
// forEach 遍历数组会自动跳过空元素
+const eachFlat = (arr = [], depth = 1) => {
+  const result = []; // 缓存递归结果
+  // 开始递归
+  (function flat(arr, depth) {
+    // forEach 会自动去除数组空位
+    arr.forEach((item) => {
+      // 控制递归深度
+      if (Array.isArray(item) && depth > 0) {
+        // 递归数组
+        flat(item, depth - 1)
+      } else {
+        // 缓存元素
+        result.push(item)
+      }
+    })
+  })(arr, depth)
+  // 返回递归结果
+  return result;
+}
+
+// for of 循环不能去除数组空位,需要手动去除
+const forFlat = (arr = [], depth = 1) => {
+  const result = [];
+  (function flat(arr, depth) {
+    for (let item of arr) {
+      if (Array.isArray(item) && depth > 0) {
+        flat(item, depth - 1)
+      } else {
+        // 去除空元素,添加非undefined元素
+        item !== void 0 && result.push(item);
+      }
+    }
+  })(arr, depth)
+  return result;
+}
+
+ +

使用堆栈stack

+ +
// 无递归数组扁平化,使用堆栈
+// 注意:深度的控制比较低效,因为需要检查每一个值的深度
+// 也可能在 shift / unshift 上进行 w/o 反转,但是末端的数组 OPs 更快
+var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]];
+function flatten(input) {
+  const stack = [...input];
+  const res = [];
+  while (stack.length) {
+    // 使用 pop 从 stack 中取出并移除值
+    const next = stack.pop();
+    if (Array.isArray(next)) {
+      // 使用 push 送回内层数组中的元素,不会改动原始输入
+      stack.push(...next);
+    } else {
+      res.push(next);
+    }
+  }
+  // 反转恢复原数组的顺序
+  return res.reverse();
+}
+flatten(arr1);// [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]
+ +
// 递归版本的反嵌套
+function flatten(array) {
+  var flattend = [];
+  (function flat(array) {
+    array.forEach(function(el) {
+      if (Array.isArray(el)) flat(el);
+      else flattend.push(el);
+    });
+  })(array);
+  return flattend;
+}
+ +

Use Generator function

+ +
function* flatten(array) {
+    for (const item of array) {
+        if (Array.isArray(item)) {
+            yield* flatten(item);
+        } else {
+            yield item;
+        }
+    }
+}
+
+var arr = [1, 2, [3, 4, [5, 6]]];
+const flattened = [...flatten(arr)];
+// [1, 2, 3, 4, 5, 6]
+ +

Please do not add polyfills on this article. For reference, please check: https://discourse.mozilla.org/t/mdn-rfc-001-mdn-wiki-pages-shouldnt-be-a-distributor-of-polyfills/24500

+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 2019FinishedInitial definition
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Array.flat")}}

+
+ +

参见

+ + -- cgit v1.2.3-54-g00ecf