繁体   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