[英]How do I flatten part of a multidimensional array one level only?
我有一個復雜的JSON對象。 我正在嘗試對其進行處理以創建一個看起來像這樣的數組:
[
[ "Name", "Spec", "Spec" ],
[ "Name", "Spec", "Spec" ]
]
這就是我被困的地方:
let array = products.map((product) => {
return [
product.name,
product.attributes
.map((attribute) => (
attribute.spec
))
.reduce((accumulator, currentValue) => {
return accumulator.concat(currentValue);
}, [])
];
});
結果如下:
[
[ "Name", [ "Spec", "Spec" ] ],
[ "Name", [ "Spec", "Spec" ] ]
]
誠然,我不完全了解reduce
方法,這里是initialValue
參數。 我知道使用該方法可以在使用map
的頂層使用平坦化數組,但是在更深層次上,似乎什么也沒做。
我在網上搜索過,但僅找到涉及完全拉平深層陣列的答案。 由於缺乏兼容性, flatten()
方法不是一個選擇。
有人可以建議僅將第二級展平嗎? 如果可能的話,我想通過改變數組來實現。
您不需要那里的減速器-它只是使事情變得不必要地復雜。 將attributes
映射到其spec
屬性,然后使用傳播:
const array = products.map(({ name, attributes }) => {
const specs = attributes.map(attribute => attribute.spec);
return [name, ...specs];
});
您將reduce
放置在錯誤的位置。 您正在整理規格列表,該列表已經是平面陣列。 您想要拼合具有名稱和規格列表的列表。 這是一種可能性:
const array = products.map(prod => [
prod.name,
prod.attributes.map(attr => attr.spec)
].reduce((acc, curr) => acc.concat(curr), []));
正如SomePerformance指出的那樣,有一個更簡單的版本,我可能會寫得有些不同
const array = products.map(({name, attributes}) =>
[name, ...attributes.map(attr => attr.spec)]
);
flatten
該怎么辦? 從第一個解決方案中提取它作為可重用函數。 這不能完全替代新的Array flatten
方法,但可能僅是您所需要的:
const flatten = arr => arr.reduce((acc, curr) => acc.concat(curr), [])
const array = products.map(prod => flatten([
prod.name,
prod.attributes.map(attr => attr.spec)
])
)
reduce
通話扁平化? 我們可以認為[x, y, z].reduce(fn, initial)
執行這些步驟
fn(initial, x)
,產生值a
fn(a, y)
,得到值b
fn(b, z)
,產生值c
c
換句話說, [x, y, z].reduce(fn, initial)
返回fn(fn(fn(initial, x), y), z)
。
當fn
是(acc, val) => acc.concat(val)
,我們可以將['name', ['spec1', 'spec2']].reduce(fn, [])
視為fn(fn([], 'name'), ['spec1', 'spec2'])
,與([].concat('name')).concat(['spec1', 'spec2'])
, ,當然是['name', 'spec1', 'spec2']
。
我很高興你問。 :-)
有一個重大的失敗。 您沒有包含任何樣本數據。 為了解決此問題,需要嘗試從代碼中重建數據格式。 舉一個簡單的例子就很容易了,例如:
const products = [
{name: 'foo', attributes: [{spec: 'bar'}, {spec: 'baz'}]},
{name: 'oof', attributes: [{spec: 'rab'}, {spec: 'zab'}]}
]
具有匹配的預期輸出:
[
["foo", "bar", "baz"],
["oof", "rab", "zab"]
]
既然您提到了它,這似乎是一個奇怪的結構。 您可能有充分的理由,但這很奇怪。
數組通常在JavaScript中有兩個用途。 它們或者是相同類型的元素的任意長度列表,或者是固定長度的列表,在每個索引處都有特定的類型(也稱為元組) 。
但是您的結構將這兩者結合在一起。 它們是任意的(至少看起來是這樣)長度列表,其中第一個條目是名稱,而后一個是規范。 盡管可能有理由,但您可能需要考慮這種結構是否特別有用。
如果可能的話,我想通過改變數組來實現。
我拒絕參加這樣的恐怖活動。
嚴重的是,不可變的數據使編碼變得非常容易。 您將其列為要求的任何真正原因嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.