簡體   English   中英

如何僅將多維數組的一部分展平到一級?

[英]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];
});

1.為什么會失敗?

您將reduce放置在錯誤的位置。 您正在整理規格列表,該列表已經是平面陣列。 您想要拼合具有名稱和規格列表的列表。 這是一種可能性:

const array = products.map(prod => [
  prod.name,
  prod.attributes.map(attr => attr.spec)
].reduce((acc, curr) => acc.concat(curr), []));

2.有什么更好的解決方案?

正如SomePerformance指出的那樣,有一個更簡單的版本,我可能會寫得有些不同

const array = products.map(({name, attributes}) =>
  [name, ...attributes.map(attr => attr.spec)]
);

3.如果我需要在其他地方重新使用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)
  ])
)

4.如何reduce通話扁平化?

我們可以認為[x, y, z].reduce(fn, initial)執行這些步驟

  1. 調用fn(initial, x) ,產生值a
  2. 調用fn(a, y) ,得到值b
  3. 調用fn(b, z) ,產生值c
  4. 由於數組已用盡,因此返回值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']

5.我的問題有什么問題嗎?

我很高興你問。 :-)

有一個重大的失敗。 您沒有包含任何樣本數據。 為了解決此問題,需要嘗試從代碼中重建數據格式。 舉一個簡單的例子就很容易了,例如:

const products = [
  {name: 'foo', attributes: [{spec: 'bar'}, {spec: 'baz'}]},
  {name: 'oof', attributes: [{spec: 'rab'}, {spec: 'zab'}]}
]

具有匹配的預期輸出:

[
  ["foo", "bar", "baz"], 
  ["oof", "rab", "zab"]
]

6.我的輸出結構如何?

既然您提到了它,這似乎是一個奇怪的結構。 您可能有充分的理由,但這很奇怪。

數組通常在JavaScript中有兩個用途。 它們或者是相同類型的元素的任意長度列表,或者是固定長度的列表,在每個索引處都有特定的類型(也稱為元組)

但是您的結構將這兩者結合在一起。 它們是任意的(至少看起來是這樣)長度列表,其中第一個條目是名稱,而后一個是規范。 盡管可能有理由,但您可能需要考慮這種結構是否特別有用。

7.如何做到這一點而又不會變異?

如果可能的話,我想通過改變數組來實現。

我拒絕參加這樣的恐怖活動。

嚴重的是,不可變的數據使編碼變得非常容易。 您將其列為要求的任何真正原因嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM