update a specific index of an array when using spread operator

Can we allow dynamic index of arrays to be update/add via a spread operator just like we do for objects, e.g here a reducer example:

const state = { myObj: {items: ["a", "b", "c"]} };
const index = 2;
const newValue = "d";

return {
   ...state,
   myObj: {
       ...state.myObj,
      items: [
        ...state.myObj.items,
        [index]: newValue, // do something like this
      ]
   }
} // => { myObj: {items: ["a", "b", "d"]} };

This has been requested at least 3 times on Stackoverflow, so its seems like natural pattern people want to use.

[1] References

Thanks

no, because array destructuring syntax is actually iterator destructuring syntax, and iterators don't have indexes.

You could use with.

const state = { myObj: {items: ["a", "b", "c"]} };
const index = 2;
const newValue = "d";

return {
   ...state,
   myObj: {
       ...state.myObj,
      items: state.myObj.items.with(index, newValue)
   }
}
4 Likes

They're talking about creation, not destructuring. Destructuring could literally just be done via const {[index]: value} = someArray for const value = someArray[index], and I've lately even started doing const {1: value} = result for extracting groups in RegExp.prototype.exec results (typically for ones I know will match).

To this goal, you could spec [...prev, [key]: value, a, ...next] to align more with how object properties are evaluated in the face of object spread:

// Loosely what'd happen under the hood
let $result = []
// ...prev
for (let $i of prev) $result.push($i)
// [index]: value
$result[key] = value
// a
$result.push(a)
// ...next
for (let $i of next) $result.push($i)
return $result