{"action":"created","issue":{"url":"https://api.github.com/repos/facebook/immutable-js/issues/762","repository_url":"https://api.github.com/repos/facebook/immutable-js","labels_url":"https://api.github.com/repos/facebook/immutable-js/issues/762/labels{/name}","comments_url":"https://api.github.com/repos/facebook/immutable-js/issues/762/comments","events_url":"https://api.github.com/repos/facebook/immutable-js/issues/762/events","html_url":"https://github.com/facebook/immutable-js/issues/762","id":126934938,"number":762,"title":"Map.mergeDeep - how to avoid merging Lists within","user":{"login":"ntgn81","id":4622542,"avatar_url":"https://avatars.githubusercontent.com/u/4622542?v=3","gravatar_id":"","url":"https://api.github.com/users/ntgn81","html_url":"https://github.com/ntgn81","followers_url":"https://api.github.com/users/ntgn81/followers","following_url":"https://api.github.com/users/ntgn81/following{/other_user}","gists_url":"https://api.github.com/users/ntgn81/gists{/gist_id}","starred_url":"https://api.github.com/users/ntgn81/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ntgn81/subscriptions","organizations_url":"https://api.github.com/users/ntgn81/orgs","repos_url":"https://api.github.com/users/ntgn81/repos","events_url":"https://api.github.com/users/ntgn81/events{/privacy}","received_events_url":"https://api.github.com/users/ntgn81/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-01-15T18:56:31Z","updated_at":"2016-04-16T01:32:50Z","closed_at":"2016-04-16T01:32:50Z","body":"I would like to use `mergeDeep` to merge my deeply nested state object, but not try to merge the Lists whenever it sees them\r\n\r\nSimple example. More detailed sample below.\r\n\r\n```js\r\nvar originalData = {person: { name: 'John', skills: ['drinking', 'eating']}};\r\nvar originalState = Immutable.fromJS(originalData);\r\nvar updatedData = {person: {name: 'John Doe', skills: ['sleeping']}};\r\nvar updatedState = originalState.mergeDeep(updatedData);\r\nupdatedState.toJS().person.skills; // [\"sleeping\", \"eating\"]\r\n```\r\n\r\nI need the arrays to be ovewritten, not merged. I understand that `mergeDeep` is designed that way. I am just wondering if there's an easier way to achieve what I need. Right now I am doing this:\r\n\r\n\r\n1. Traverse `updatedData` object, find properties that are `Array.isArray`\r\n2. When found\r\n  - get the path to the current entry\r\n  - use `setIn()`, passing that array\r\n  - delete that array node from `updatedData` to lighten the load for mergeDeep\r\n  ```js\r\n  // mergeDeep that replaces arrays with instead of merging\r\n  function mergeDeepReplaceArrays (state, updatedData) {\r\n    const replaceArrays = (data, basePath) => {\r\n      basePath = basePath || [];\r\n      _.forIn(data, (v, k) => {\r\n        const path = basePath.concat([k]);\r\n        if (Array.isArray(v)) {\r\n          if (state.hasIn(path)) {\r\n            state = state.setIn(path, Immutable.fromJS(v));\r\n            delete data[k];\r\n          }\r\n        } else if (_.isObject(v)) {\r\n          replaceArrays(v, path);\r\n        }\r\n      });\r\n    };\r\n    replaceArrays(updatedData);\r\n    return state.mergeDeep(updatedData);\r\n  }\r\n  ````\r\n\r\nThis definitely seems hacky and weird. Would be nice, I think, to have a hook into `mergeDeep`, similar to `mergeDeepWith`, except for when the optional `merger` will be called for every node, giving original/target rather than just on the conflicts.\r\n\r\nEdit: Updated the code to use `withMutations`, making it a bit faster, but for some weird reasons, my hacky/crappy code is faster than plain `mergeDeep`, according to jsPerf: http://jsperf.com/withmutations-test\r\n\r\n\r\nMore detailed sample\r\n\r\n```js\r\n// Initial entities\r\nvar entities = Immutable.fromJS({\r\n  products: {\r\n    '1': {\r\n      name: 'iPhone',\r\n      categories: ['tech', 'phone', 'mobile']\r\n    },\r\n    '2': {\r\n      name: 'Apple',\r\n      categories: ['food', 'fruit']\r\n    },\r\n    '3': {\r\n      name: 'Jacket X',\r\n      categories: ['clothing']\r\n    }\r\n  },\r\n\r\n  // list of product ids\r\n  carts: {\r\n    '1': {\r\n      name: 'First Cart',\r\n      items: [1, 2, 3]\r\n    },\r\n    '2': {\r\n      name: 'Second Cart',\r\n      items: [3]\r\n    }\r\n  }\r\n})\r\n```\r\n\r\nA change occured to some items:\r\n  - `iPhone`\r\n    - Has `tech` category removed\r\n  - `First Cart`:\r\n   - Item `2` is removed\r\n   - Name is changed\r\n\r\n```js\r\nvar entitiesUpdate = {\r\n  products: {\r\n    '1': {\r\n      name: 'iPhone',\r\n      categories: ['phone', 'mobile']\r\n    }\r\n  }\r\n  carts: {\r\n    '1': {\r\n      name: 'First Cart updated',\r\n      items: [1, 3]\r\n    }\r\n  }\r\n}\r\n```\r\n\r\nI need the arrays at  `products['1'].categories` and `carts['1'].items` to be replaced to properly reflect the update, not merged into `['phone', 'mobile', 'mobile']` and `[1, 3, 3]` respectively.\r\n\r\n\r\n\r\n\r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/facebook/immutable-js/issues/comments/210705647","html_url":"https://github.com/facebook/immutable-js/issues/762#issuecomment-210705647","issue_url":"https://api.github.com/repos/facebook/immutable-js/issues/762","id":210705647,"user":{"login":"leebyron","id":50130,"avatar_url":"https://avatars.githubusercontent.com/u/50130?v=3","gravatar_id":"","url":"https://api.github.com/users/leebyron","html_url":"https://github.com/leebyron","followers_url":"https://api.github.com/users/leebyron/followers","following_url":"https://api.github.com/users/leebyron/following{/other_user}","gists_url":"https://api.github.com/users/leebyron/gists{/gist_id}","starred_url":"https://api.github.com/users/leebyron/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/leebyron/subscriptions","organizations_url":"https://api.github.com/users/leebyron/orgs","repos_url":"https://api.github.com/users/leebyron/repos","events_url":"https://api.github.com/users/leebyron/events{/privacy}","received_events_url":"https://api.github.com/users/leebyron/received_events","type":"User","site_admin":false},"created_at":"2016-04-16T01:32:50Z","updated_at":"2016-04-16T01:32:50Z","body":"Best to ask this type of question on Stack Overflow where there is more traffic. https://stackoverflow.com/questions/tagged/immutable.js?sort=votes\r\n\r\nThe answer likely includes `mergeDeepWith` which allows for a custom merge function."}}