Skip to content

Instantly share code, notes, and snippets.

@joecritch joecritch/updatein.js
Last active Oct 10, 2017

Embed
What would you like to do?
Immutable tree "updateIn"
function updateIn(tree, indexPath, replacement, childrenKey = 'children', depth = 0) {
function insert(ins) {
return tree
.slice(0, indexPath[depth])
.concat([ins])
.concat(tree.slice(indexPath[depth] + 1));
}
const lastDepth = indexPath.length - 1;
// Edge case: reached the leaf node.
if (depth === lastDepth) {
if (replacement === null) {
// Remove the node at last index
return tree.filter((el, idx) => idx !== indexPath[depth]);
}
return insert(replacement);
}
let node = tree[indexPath[depth]];
if (node[childrenKey] && depth < lastDepth) {
// Recursive case: we've hit a Block along the index path
node = {
...node,
[childrenKey]: updateIn(node.children, indexPath, replacement, childrenKey, depth + 1),
};
}
// Return case
return insert(node);
}

updateIn

Replaces a node in a tree's given index path, and returns a new object. Reuses existing objects where possible.

Useful for updating recursive & immutable data structures in React or Redux.

usage

const tree = [
  {
    name: 'parent',
    children: [
      {
        name: 'child 1',
      },
      {
        name: 'child 2',
      },
    ],
  },
  {
    name: 'another parent',
    children: null,
  },
];

const newTree = updateIn(tree, [0, 1], { name: 'child 2a' });

// newTree shape:
// [
//   {
//     name: 'parent',
//     children: [
//       {
//         name: 'child 1',
//       },
//       {
//         name: 'child 2a',
//       },
//     ],
//   },
//   {
//     name: 'another parent',
//     children: null,
//   },
// ]

// equality:
// newTree !== tree
// newTree[0] !== tree[0]
// newTree[0].children[0] === tree[0].children[0]
// newTree[0].children[1] !== tree[0].children[1]
// newTree[1] === tree[1]

removing a node

const newTree = updateIn(tree, [0, 1], null);
  • pass null as the replacement
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.