Seemed quite intuitive to me, but turns out that's not how things work! The goal is to remove the passed element if it exists and return the rest. I know there's a number of ways of achieving this - including filter
: const rest = selection.filter(i => i !== item)
- but, as I said, thought this approach would be a thing - as it is for objects/key:value pairs
.
if (selection.includes(item)) {
// remove if available
const [item, ...rest] = selection;
setSelection(rest)
} else {
// ...
}
The way destructuring
works is it assigns the first
element of selection
to item and assigns the rest of the items to rest
- an array. Which is correct - that's how things work, from my understanding at least.
Is it possible to extract a specific item from an array and unpack the rest of the elements to a variable by using destructuring assignment ?
Seemed quite intuitive to me, but turns out that's not how things work! The goal is to remove the passed element if it exists and return the rest. I know there's a number of ways of achieving this - including filter
: const rest = selection.filter(i => i !== item)
- but, as I said, thought this approach would be a thing - as it is for objects/key:value pairs
.
if (selection.includes(item)) {
// remove if available
const [item, ...rest] = selection;
setSelection(rest)
} else {
// ...
}
The way destructuring
works is it assigns the first
element of selection
to item and assigns the rest of the items to rest
- an array. Which is correct - that's how things work, from my understanding at least.
Is it possible to extract a specific item from an array and unpack the rest of the elements to a variable by using destructuring assignment ?
Share Improve this question edited Mar 25, 2023 at 11:34 Gass 9,4605 gold badges47 silver badges53 bronze badges asked Jan 6, 2021 at 6:24 kawerewagabakawerewagaba 1,3772 gold badges17 silver badges21 bronze badges 5- 1 Use filter. What you are trying to do with destructuring is not possible. – Omkar76 Commented Jan 6, 2021 at 6:34
- 1 you could do an ugly hack: jsfiddle/tfca7ow9, but don't use that :P – Nick Parsons Commented Jan 6, 2021 at 6:38
- Turns out it's possible, as shown by @NickParsons and Brett Zamir - downside being it's more work - at least with the current implementation. – kawerewagaba Commented Jan 6, 2021 at 8:03
-
@Omkar76 I definitely used filter - just thought there could be a more "elegant" way. I also didn't want to conclude with
not possible
before I heard from the munity – kawerewagaba Commented Jan 6, 2021 at 8:06 - 1 @colinwagaba, I get your point. I didn't think about destructuring array to an object. I know I should be more careful saying not possible next time =) – Omkar76 Commented Jan 6, 2021 at 9:00
2 Answers
Reset to default 4Here's a strange way it could be done:
const item = 5
const selection = [3, 4, 5, 6]
const itemPos = selection.indexOf(item)
if (selection.includes(item)) {
// remove if available
const {[itemPos]: item, ...rest} = selection
// `rest` is now an object, so convert back to an array:
console.log(Object.values(rest)) // [3, 4, 6]
setSelection(Object.values(rest))
} else {
// ...
}
Since I used const
in both places, the second item
is a different one, but one could remove const
and wrap the expression in parentheses to reassign item
(as I think you had originally requested):
let rest, item = 5
const selection = [3, 4, 5, 6]
const itemPos = selection.indexOf(item)
if (selection.includes(item)) {
// remove if available
({[itemPos]: item, ...rest} = selection)
console.log(Object.values(rest)) // [3, 4, 6]
setSelection(Object.values(rest))
} else {
// ...
}
But if you wanted to follow a similar pattern without using filter
, you could use splice
:
const item = 5
const selection = [3, 4, 5, 6]
const itemPos = selection.indexOf(item)
if (selection.includes(item)) {
// remove if available
const rest = [...selection] // Copy array if you still need `selection`; otherwise, we could just splice and pass `selection`
rest.splice(itemPos, 1)
console.log(rest)
setSelection(rest)
} else {
// ...
}
None of these are especially appealing pared to filter
, but it should show how the approaches would work.
First, we need to be aware that arrays in JS can be treated as objects.
As you can see here:
console.log(typeof [0,1,2])
Okay, so... now if we read the syntax of destructuring assignments we can see that there is the possibility to extract an specific element from an object by using its key.
const { [key]: a } = obj
For example:
const arr = ["