1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
---
title: Array.prototype.flatMap()
slug: Web/JavaScript/Reference/Global_Objects/Array/flatMap
tags:
- Array
- JavaScript
- Method
- Prototype
- Reference
translation_of: Web/JavaScript/Reference/Global_Objects/Array/flatMap
---
<div>{{JSRef}}</div>
<p><code><strong>flatMap()</strong></code> 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map">map</a> 连着深度值为1的 <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat">flat</a> 几乎相同,但 <code>flatMap</code> 通常在合并成一种方法的效率稍微高一些。</p>
<p class="hidden">\{{EmbedInteractiveExample("pages/js/array-flatmap.html")}}</p>
<p class="hidden">此交互式示例的源代码存储在GitHub存储库中。如果您想要为交互式示例项目做出贡献,请复制https://github.com/mdn/interactive-examples,并向我们发送 pull request。</p>
<h2 id="语法">语法</h2>
<pre class="syntaxbox notranslate"><var>var new_array = arr</var>.flatMap(function <var>callback(currentValue[, index[, array]]) {
// return element for new_array
}</var>[, <var>thisArg</var>])</pre>
<h3 id="参数">参数</h3>
<dl>
<dt><code>callback</code></dt>
<dd>可以生成一个新数组中的元素的函数,可以传入三个参数:
<dl>
<dt></dt>
<dt><code>currentValue</code></dt>
<dd>当前正在数组中处理的元素</dd>
<dt><code>index</code>{{optional_inline}}</dt>
<dd>可选的。数组中正在处理的当前元素的索引。</dd>
<dt><code>array</code>{{optional_inline}}</dt>
<dd>可选的。被调用的 <code>map</code> 数组</dd>
</dl>
</dd>
<dt><code>thisArg</code>{{optional_inline}}</dt>
<dd>可选的。执行 <code>callback</code> 函数时 使用的<code>this</code> 值。</dd>
</dl>
<h3 id="返回值">返回值</h3>
<p> 一个新的数组,其中每个元素都是回调函数的结果,并且结构深度 <code>depth</code> 值为1。</p>
<h2 id="描述">描述</h2>
<p>有关回调函数的详细描述,请参见 {{jsxref("Array.prototype.map()")}} 。 <code>flatMap</code> 方法与 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map">map</a></code> 方法和深度depth为1的 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat">flat</a></code> 几乎相同.</p>
<h2 id="示例">示例</h2>
<h3 id="map_与_flatMap"><code>map()</code> 与 <code>flatMap()</code></h3>
<pre class="brush: js notranslate">var arr1 = <span class="js source"><span class="function-call js meta"><span class="js meta"><span class="brace js meta square"><span>[</span></span><span class="constant decimal js numeric"><span>1</span></span><span class="comma delimiter js meta object"><span>,</span></span><span> </span><span class="brace js meta square"><span>2, 3, 4];
arr1.map(</span></span></span></span></span>x => [x * 2]<span class="js source"><span class="function-call js meta"><span class="js meta"><span class="brace js meta square"><span>);</span></span></span></span></span>
// [[2], [4], [6], [8]]
arr1.flatMap(x => [x * 2]<span class="js source"><span class="function-call js meta"><span class="js meta"><span class="brace js meta square"><span>);
// [2, 4, 6, 8]</span></span></span></span></span>
// <code>only one level is flatt</code><code>ened</code>
arr1.flatMap(x => [[x * 2]]);
// [[2], [4], [6], [8]]</pre>
<p>虽然上面的代码使用 map 和 flatMap 好像都可以,但这只能展示如何使用 flatMap。</p>
<p>所以,为了更好的展示 flatMap 的作用,下面我们将包含几句话的数组拆分成单个词组成的新数组。</p>
<pre class="notranslate"><code>let arr1 = ["it's Sunny in", "", "California"];
arr1.map(x => x.split(" "));
// [["it's","Sunny","in"],[""],["California"]]
arr1.flatMap(x => x.split(" "));
// ["it's","Sunny","in", "", "California"]</code></pre>
<p>注意,输出列表长度可以不同于输入列表长度。</p>
<h3 id="在一个_map_期间增加或去除一些项">在一个 <code>map()</code> 期间增加或去除一些项</h3>
<p><code>flatMap</code> 能用于在map期间增删项目(也就是修改items的数量)。换句话说,它允许你遍历很多项使之成为另一些项(靠分别把它们放进去来处理),而不是总是一对一。 从这个意义上讲,它的作用类似于 <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter">filter</a>的对立面。只需返回一个1项元素数组以保留该项,返回一个多元素数组以添加项,或返回一个0项元素数组以删除该项。</p>
<pre class="notranslate"><code>// Let's say we want to remove all the negative numbers and split the odd numbers into an even number and a 1
let a = [5, 4, -3, 20, 17, -33, -4, 18]
// |\ \ x | | \ x x |
// [4,1, 4, 20, 16, 1, 18]
a.flatMap( (n) =>
(n < 0) ? [] :
(n % 2 == 0) ? [n] :
[n-1, 1]
)
// expected output: [4, 1, 4, 20, 16, 1, 18]</code></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.flatMap(x => [x, x * 2]);
// is equivalent to
arr.reduce((acc, x) => acc.concat([x, x * 2]), []);
// [1, 2, 2, 4, 3, 6, 4, 8]</code></pre>
<p>请注意,这是低效的,并且应该避免大型阵列:在每次迭代中,它创建一个必须被垃圾收集的新临时数组,并且它将元素从当前的累加器数组复制到一个新的数组中,而不是将新的元素添加到现有的数组中。</p>
<div class="hidden">
<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>
</div>
<h2 id="规范">规范</h2>
<table class="standard-table">
<tbody>
<tr>
<td>Specification</td>
<td>Status</td>
<td>Comment</td>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-array.prototype.flatmap', 'Array.prototype.flatMap')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td></td>
</tr>
</tbody>
</table>
<h2 id="浏览器兼容性">浏览器兼容性</h2>
<div class="hidden">
<p>The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p>
</div>
<p>{{Compat("javascript.builtins.Array.flatMap")}}</p>
<h2 id="参见">参见</h2>
<ul>
<li>{{jsxref("Array.prototype.flat()")}}</li>
<li>{{jsxref("Array.prototype.map()")}}</li>
<li>{{jsxref("Array.prototype.reduce()")}}</li>
<li>{{jsxref("Array.prototype.concat()")}}</li>
</ul>
|