Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
315 views
in Technique[技术] by (71.8m points)

javascript - Destructure object properties inside array for all elements

In its most basic form, having an array of objects:

let arr = [
  {val:"a"},
  {val:"b"}
];

How can destructuring be used, to obtain only the values ['a', 'b'].

getting the first value is easy:

let [{val:res}] = arr; //res contains 'a'

Obtaining all values inside the array can be done with the rest operator:

let [...res] = arr; //res contains all objects

Combining those, I expected to be able to use:

let [...{val:res}] = arr; //undefined, expected all 'val's (['a', 'b'])

The above returns undefined (Tested in FF). Some further testing seems to indicate that adding the rest operator when using an object destructuring as well doesn't use the iteration, but gets back the original object, e.g. let [...{length:res}] = arr; //res= 2. Some other trials, such as let [{val:...res}] = arr; or let [{val}:...res] = arr; produce syntax errors.

It's easy enough to do with other methods, such as using map on the array, but mostly I stumble upon this problem while destructuring multiple levels (an array with objects which have their own property containing an array). Therefore I'm really trying to get around how to do it solely with destructuring. For convenience: a test fiddle

edit

My apologies if I failed to explain the goal of the question. I'm not looking for a solution to a specific problem, only to find the correct syntax to use when destructuring.

Otherwise formulated, a first question would be: in the example above, why doesn't let [...{val:res}] = arr; return all values (['a', 'b']). The second question would be: what is the proper syntax to use a rest operator with a nested object destructuring? (pretty sure I've gotten some definitions mixed up here). It seems that the latter is not supported, but I haven't come across any documentation that (and why) it wouldn't be.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Why doesn't let [...{val:res}] = arr; return all values (['a', 'b'])?

You seem to confuse the rest syntax with array comprehensions.

If you assign a value to [someElements, ...someExpression], the value is tested to be iterable and then each element generated by the iterator is assigned to the respective someElements variable. If you use the rest syntax in the destructuring expression, an array is created and the iterator is ran till its end while filling the array with the generated values. Then that array is assigned to the someExpression.

All of these assignment targets can be other destructuring expressions (arbitrarily nested and recursively evaluated), or references to variable or properties.

So if you do let [...{val:res}] = arr, it will create an array and fill that with all the values from the iterator of arr:

let {val:res} = Array.from(arr[Symbol.iterator]())

You can see now why that ends up with undefined, and why using something like [...{length:res}] does yield a result. Another example:

let [{val:res1}, ...{length: res2}] = arr;
console.log(res1) // 'a'
console.log(res2) // 1 (length of `[{val: 'b'}]`)

How can destructuring be used to obtain only the values ['a', 'b']?

Not at all. Use the map method.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...