为所有元素解构数组内的对象属性
Posted
技术标签:
【中文标题】为所有元素解构数组内的对象属性【英文标题】:Destructure object properties inside array for all elements 【发布时间】:2017-02-25 10:17:23 【问题描述】:在其最基本的形式中,有一个对象数组:
let arr = [
val:"a",
val:"b"
];
如何使用解构,只获取值['a', 'b']
。
获取第一个值很容易:
let [val:res] = arr; //res contains 'a'
可以通过rest操作符来获取数组中的所有值:
let [...res] = arr; //res contains all objects
结合这些,我希望能够使用:
let [...val:res] = arr; //undefined, expected all 'val's (['a', 'b'])
以上返回未定义(在 FF 中测试)。一些进一步的测试似乎表明,在使用对象解构时添加 rest 运算符也不会使用迭代,而是取回原始对象,例如let [...length:res] = arr; //res= 2
。其他一些试验,例如let [val:...res] = arr;
或let [val:...res] = arr;
会产生语法错误。
使用其他方法很容易,例如在数组上使用map
,但大多数情况下,我在解构多个级别(具有包含数组的对象的数组)时偶然发现了这个问题。因此,我真的在尝试解决如何仅通过解构来做到这一点。
为方便起见:a test fiddle
编辑
如果我未能解释问题的目标,我深表歉意。我不是在寻找特定问题的解决方案,只是为了找到解构时使用的正确语法。
否则,第一个问题将是:在上面的示例中,为什么let [...val:res] = arr;
不返回所有值(['a', 'b']
)。第二个问题是:在嵌套对象解构中使用 rest 运算符的正确语法是什么? (很确定我在这里混淆了一些定义)。似乎不支持后者,但我没有遇到任何不支持(以及为什么)不支持的文档。
【问题讨论】:
你希望res
在这样的解构过程中变成什么?什么是“所有 vals”?
@Bergi 我原以为它会返回['a', 'b']
(它是let [val:res] = arr;
和let [...res] = arr;
的组合)
@Me.Name "第二个问题是:在嵌套对象解构中使用 rest 运算符的正确语法是什么?(很确定我在这里混淆了一些定义)。” 见What is SpreadElement in ECMAScript documentation? Is it the same as Spread operator at MDN?
@Me.Name 是否要求不使用函数调用或循环?
【参考方案1】:
此时您可以同时使用For of loop 和ES6 Object destructuring。
let arr = [val:"a",val:"b"];
for (const item in arr)
const val = arr[item];
console.log(val);
【讨论】:
【参考方案2】:可以在解构赋值之前声明赋值目标;在解构目标处,通过从解构源设置赋值目标索引的值
let arr1 = [val: "a", val: "b"];
let arr2 = ["foo":1,"arr":["val":"a","val":"b"]
, "foo":2,"arr":["val":"c","val":"d"]];
let [res1, res2] = [[], []];
[val: res1[0], val: res1[1]] = arr1;
[arr: [val:res2[0], val:res2[1]]
, arr: [val:res2[2], val:res2[3]]] = arr2;
console.log(res1, res2);
您也可以在目标中使用rest element
在源中收集值,方法是按照对象模式包含comma
运算符以返回从对象中提取的值
let arr = [val: "a", val: "b"];
let [...res] = [(val = arr[0], val), (val = arr[1], val)];
console.log(res)
【讨论】:
【参考方案3】:为什么
let [...val:res] = arr;
不返回所有值 (['a', 'b']
)?
您似乎将其余语法与数组推导混淆了。
如果您为[someElements, ...someExpression]
分配一个值,该值将被测试为可迭代,然后将迭代器生成的每个元素分配给相应的someElements
变量。如果在解构表达式中使用 rest 语法,则会创建一个数组并运行迭代器直到其结束,同时用生成的值填充数组。然后将该数组分配给someExpression
。
所有这些赋值目标都可以是其他解构表达式(任意嵌套和递归计算),或者对变量或属性的引用。
因此,如果您执行let [...val:res] = arr
,它将创建一个数组并用来自arr
的迭代器的所有值填充:
let val:res = Array.from(arr[Symbol.iterator]())
您现在可以看到为什么以undefined
结尾,以及为什么使用[...length:res]
之类的东西确实会产生结果。另一个例子:
let [val:res1, ...length: res2] = arr;
console.log(res1) // 'a'
console.log(res2) // 1 (length of `[val: 'b']`)
如何使用解构来仅获取值
['a', 'b']
?
一点也不。使用map
方法。
【讨论】:
@guest271314 为什么?如果您参考您的帖子,这与我的回答有什么关系? "可以使用解构来仅获取值['a', 'b']
?"。您答案的“根本不是”部分。可以通过为从=
右侧的输入数组中检索到的每个预期值声明一个唯一变量,然后将定义的变量推送到数组中。尝试使用spread
元素在使用[prop]: [...res]
的解构赋值中扩展数组,但尚未找到在下一个赋值索引处将"a"
扩展为res
的方法
@guest271314 如果声明多个变量,则它不适用于任意长度的数组。如果你使用循环,那么就不再是解构了。
没有考虑任意长度的数组,因为 OP 的数组只包含四个元素。对于任意长度的数组,这里的第一印象是尝试将变量分配为对象的属性,而不是例如a
;不确定这是否可能。会尝试这种方法。此处发表评论的原因是由于您的答案的“根本没有”部分。如果您对答案的那部分没问题,我也在这里。还发表了评论,因为您可能会注意到答案的该部分可能有所改进
看看你的意思...
【参考方案4】:
除了映射与值的回调
let arr = [ val: "a" , val: "b" ];
console.log(arr.map(o => o.val));
您可以在参数列表中使用解构并仅使用返回的值。
let arr = [ val: "a" , val: "b" ];
console.log(arr.map((val) => val));
【讨论】:
嗨,尼娜。谢谢你回复我的帖子。我一直很喜欢你的帖子和你提供的简洁答案:) 但是在这种情况下,它不是关于特定场景,而是为了找到一个通用的语法解决方案。我认为有一种语法可以对未知数量的元素进行解构,因此可以在[foo:1, arr:[ val:"a", val:"b"],foo:2, arr:[ val:"c", val:"d"] ]
上使用相同的语法
我的误解是你想要达到的结果。我(非常)依赖示例,对我来说,不清楚你想要实现什么。我看不到对象是源对象还是目标对象。如果您包括源和目标,也许 itz 会更清楚。
我们的目标是找出如何(以及是否)可以使用解构来获取多个值,例如这样。既然存在rest
运算符(let [...res] = arr;
有效)并且允许嵌套属性,为什么let [...val:res] = arr;
不给出所有值。我以为这是我的某种疏忽,但我开始担心这是不可能的。不是具体的问题或例子,所以恐怕不能给出具体的来源和目标,只能举例。【参考方案5】:
你可以像这样解构嵌套对象
https://developer.mozilla.org/en/docs/Web/javascript/Reference/Operators/Destructuring_assignment#Nested_object_and_array_destructuring
let arr = [
val:"a",
val:"b"
];
const [val: valueOfA, val: valueOfB] = arr
console.log(
valueOfA, valueOfB
)
【讨论】:
感谢您的回答。我知道map
可以使用,我也可以使用for(val:v of arr) console.log(v);
来组合解构和循环,甚至在map
中使用解构,但是如果rest运算符可以用于对象本身并且解构可以用于嵌套属性,为什么不能在对象解构上使用rest运算符?我找不到关于它的支持的文档,但也没有关于它不受支持的文档。
其实我完全不正确。您可以解构嵌套对象
一次每个元素确实是可能的,但是对于未知数量的条目,您将如何做呢? (不包括for..of
)
@Me.Name "(not count for..of )" 为什么不能使用for..of
?要求是什么?
for...of
是一个迭代器循环,每次迭代都会声明变量,与for...in
或for
循环不同以上是关于为所有元素解构数组内的对象属性的主要内容,如果未能解决你的问题,请参考以下文章