diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
commit | 33058f2b292b3a581333bdfb21b8f671898c5060 (patch) | |
tree | 51c3e392513ec574331b2d3f85c394445ea803c6 /files/zh-cn/web/javascript/reference/global_objects/array/flat | |
parent | 8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff) | |
download | translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2 translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip |
initial commit
Diffstat (limited to 'files/zh-cn/web/javascript/reference/global_objects/array/flat')
-rw-r--r-- | files/zh-cn/web/javascript/reference/global_objects/array/flat/index.html | 218 |
1 files changed, 218 insertions, 0 deletions
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 +--- +<div>{{JSRef}}</div> + +<p><code><strong>flat()</strong></code> 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。</p> + +<div>{{EmbedInteractiveExample("pages/js/array-flat.html")}}</div> + + + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox notranslate"><var>var newArray = arr</var>.flat([<var>depth]</var>)</pre> + +<h3 id="参数">参数</h3> + +<dl> + <dt><code>depth</code> {{optional_inline}}</dt> + <dd>指定要提取嵌套数组的结构深度,默认值为 1。</dd> +</dl> + +<h3 id="返回值">返回值</h3> + +<p>一个包含将数组与子数组中所有元素的新数组。</p> + +<h2 id="示例">示例</h2> + +<h3 id="扁平化嵌套数组">扁平化嵌套数组</h3> + +<pre class="notranslate">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,可展开任意深度的嵌套数组 +<code>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]</code></pre> + +<h3 id="扁平化与数组空项">扁平化与数组空项</h3> + +<p><code>flat()</code> 方法会移除数组中的空项:</p> + +<pre class="brush: js notranslate">var arr4 = [1, 2, , 4, 5]; +arr4.flat(); +// [1, 2, 4, 5]</pre> + +<h2 id="替代方案">替代方案</h2> + +<h3 id="使用_reduce_与_concat">使用 <code>reduce</code> 与 <code>concat</code></h3> + +<pre class="notranslate"><code>var arr = [1, 2, [3, 4]]; + +// 展开一层数组 +arr.flat(); +// 等效于 +arr.reduce((acc, val) => acc.concat(val), []); +// [1, 2, 3, 4] + +// 使用扩展运算符 ... +const flattened = arr => [].concat(...arr);</code></pre> + +<h3 class="brush: js" id="reduce_concat_isArray_recursivity">reduce + concat + isArray + recursivity</h3> + +<pre class="brush: js notranslate"><code>// 使用 reduce、concat 和递归展开无限多层嵌套的数组 +var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]]; +</code> +<code class="language-js"><span class="keyword token">function</span> <span class="function token">flatDeep</span><span class="punctuation token">(</span><span class="parameter token">arr<span class="punctuation token">,</span> d <span class="operator token">=</span> <span class="number token">1</span></span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">return</span> d <span class="operator token">></span> <span class="number token">0</span> <span class="operator token">?</span> arr<span class="punctuation token">.</span><span class="function token">reduce</span><span class="punctuation token">(</span><span class="punctuation token">(</span><span class="parameter token">acc<span class="punctuation token">,</span> val</span><span class="punctuation token">)</span> <span class="operator token">=></span> acc<span class="punctuation token">.</span><span class="function token">concat</span><span class="punctuation token">(</span>Array<span class="punctuation token">.</span><span class="function token">isArray</span><span class="punctuation token">(</span>val<span class="punctuation token">)</span> <span class="operator token">?</span> <span class="function token">flatDeep</span><span class="punctuation token">(</span>val<span class="punctuation token">,</span> d <span class="operator token">-</span> <span class="number token">1</span><span class="punctuation token">)</span> <span class="punctuation token">:</span> val<span class="punctuation token">)</span><span class="punctuation token">,</span> <span class="punctuation token">[</span><span class="punctuation token">]</span><span class="punctuation token">)</span> + <span class="punctuation token">:</span> arr<span class="punctuation token">.</span><span class="function token">slice</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span></code> +<code> +flatDeep(arr1, Infinity); +// [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]</code></pre> + +<h3 id="forEachisArraypushrecursivity">forEach+isArray+push+recursivity</h3> + +<pre class="brush: js notranslate">// 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; +} +</pre> + +<h3 id="使用堆栈stack">使用堆栈stack</h3> + +<pre class="notranslate">// 无递归数组扁平化,使用堆栈 +// 注意:深度的控制比较低效,因为需要检查每一个值的深度 +// 也可能在 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]</pre> + +<pre class="notranslate">// 递归版本的反嵌套 +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; +}</pre> + +<h3 id="Use_Generator_function">Use <code>Generator</code> function</h3> + +<pre class="notranslate"><code>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]</code></pre> + +<p>Please do not add polyfills on this article. For reference, please check: <a href="https://discourse.mozilla.org/t/mdn-rfc-001-mdn-wiki-pages-shouldnt-be-a-distributor-of-polyfills/24500">https://discourse.mozilla.org/t/mdn-rfc-001-mdn-wiki-pages-shouldnt-be-a-distributor-of-polyfills/24500</a></p> + +<h2 id="Specifications">Specifications</h2> + +<table> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td><a href="https://www.ecma-international.org/ecma-262/10.0/index.html#sec-array.prototype.flat">ECMAScript 2019</a></td> + <td>Finished</td> + <td>Initial definition</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容性">浏览器兼容性</h2> + +<div> + + +<p>{{Compat("javascript.builtins.Array.flat")}}</p> +</div> + +<h2 id="参见">参见</h2> + +<ul> + <li>{{jsxref("Array.prototype.flatMap()")}}</li> + <li>{{jsxref("Array.prototype.map()")}}</li> + <li>{{jsxref("Array.prototype.reduce()")}}</li> + <li>{{jsxref("Array.prototype.concat()")}}</li> +</ul> |