Skip to content

Instantly share code, notes, and snippets.

@jethrolarson
Last active June 20, 2017 18:21
Show Gist options
  • Save jethrolarson/dc545faa67d5804ad36bf3f3c72429d2 to your computer and use it in GitHub Desktop.
Save jethrolarson/dc545faa67d5804ad36bf3f3c72429d2 to your computer and use it in GitHub Desktop.
// Immutable update techniques
// mutate in place
myData.x.y.z = 7;
myData.a.b.push(9);
mydata.a.b[2] = 3;
// clone and mutate
const newData = deepCopy(myData);
newData.x.y.z = 7;
newData.a.b.push(9);
mydata.a.b[2] = 3;
// manual
const ab = myData.a.b.concat(9);
ab[2] = 3;
const newData = Object.assign(myData, {
x: Object.assign(myData.x, {
y: Object.assign(myData.x.y, {z: 7}),
}),
a: Object.assign(myData.a, {b: ab})
});
// manual with object spread
const ab = myData.a.b.concat(9);
ab[2] = 3;
const newData = {
...myData,
x: {...myData.x,
y: {...myData.x.y, z: 7},
},
a: {
...myData.a,
b: ab
}
};
// https://github.com/kolodny/immutability-helper
const newData = update(myData, {
x: {y: {z: {$set: 7}}},
a: {b: {
2: {$set: 3},
$push: [9]
}}
});
// partial.lenses
const ab = ['a', 'b'];
const ab2 = [ab, 2];
const doStuff = R.pipe(
set(['x', 'y', 'z'], 7),
modify(ab, append(9)),
set(ab2, 2)
);
const newData = doStuff(myData)
@osidenate
Copy link

osidenate commented Apr 4, 2017

Update a particular item in an Array:

const arr = ['a1', 'b2', 'c3', 'd4'];
const arr2 = arr.map(item => {
  if (item === 'b2') {
    return 'b123';
  }
  return item;
});

Alternative:

const update = (condition, newItem, arr) => arr.map(item => condition(item) ? newItem : item);

// Usage
const arr = ['a1', 'b2', 'c3', 'd4'];
const equalsOldItem = item => item === 'b2';
const newArr = update(equalsOldItem, 'b123', arr);

@jethrolarson
Copy link
Author

That's a good usecase. I've added some ways to do that to all the above examples.

@osidenate
Copy link

osidenate commented Apr 7, 2017

Add an item to an Array at a particular index:

const add = (item, index, arr) => {
    const slice1 = arr.slice(0, index);
    const slice2 = arr.slice(index, arr.length);
    return [...slice1, item, ...slice2];
};

@osidenate
Copy link

Remove an item from an Array:

const remove = (index, arr) => {
    const slice1 = arr.slice(0, index);
    const slice2 = arr.slice(index + 1, arr.length);
    return [...slice1, ...slice2];
};

@jethrolarson
Copy link
Author

@osidenate Yeah, those are good. With ramda those are remove and insert. Unfortunately they're not sufficient to do the nested updates. They do combo with lenses though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment