[英]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.