兩層 Array 就會有兩層 Map()

由 API 所傳回的 JSON 資料,實務上常常會遇到 Array 中又有 Array,而 Array 中則為 Object,而我們希望維持原本 Array 的筆數,但新增 Object 的 Property 為我們所用。

若是單層的 Array,我們毫無懸念會使用 Map(),但面對兩層 Array,該如何使用 Map() 呢 ?

Imperative


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
const data = [
[
{ firstName: 'Sam', lastName: 'Xiao'},
{ firstName: 'Kevin', lastName: 'Yang'},
{ firstName: 'Paul', lastName: 'Chen'},
],
[
{ firstName: 'John', lastName: 'Doe'},
{ firstName: 'Mike', lastName: 'Huang'},
{ firstName: 'Seven', lastName: 'Eleven'},
],
];

const result = [];

for(let i = 0; i < data.length; i++) {
const tmp = [];
for(let j = 0; j < data.length; j++) {
tmp.push({
firstName: data[i][j].firstName,
lastName: data[i][j].lastName,
fullName: `${data[i][j].firstName} ${data[i][j].lastName}`,
});
}
result.push(tmp);
}

console.log(result);

原始資料為兩層 array,除了保留遠本所有資料與筆數外,還要新增 fullName property。

若使用 Imperative 寫法,會需要兩層 for loop,並建立 temp array 加以 push

Functional


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const data = [
[
{ firstName: 'Sam', lastName: 'Xiao'},
{ firstName: 'Kevin', lastName: 'Yang'},
{ firstName: 'Paul', lastName: 'Chen'},
],
[
{ firstName: 'John', lastName: 'Doe'},
{ firstName: 'Mike', lastName: 'Huang'},
{ firstName: 'Seven', lastName: 'Eleven'},
],
];

const mapper = x => ({...x, fullName: `${x.firstName} ${x.lastName}`});
const result = data.map(x => x.map(mapper));

console.log(result);

Functional 寫法會使用 map(),因為是兩層 array,所以會是 data.map(x => x.map(x => {})) 寫法。

不要看到兩層 map() 就被嚇到,因為資料本質就是兩層 array,所以兩層 map() 無法避免,但仍然只有一個 mapper() function 而已。

map000

Conclusion


  • 不要看到兩層 map() 就害怕,因為資料本質就是兩層 array,Imperative 寫法也要兩層 for loop,所以有兩層 map() 也是合理的
2018-12-25