Repository: rtfeldman/seamless-immutable
Pull request #188 (2016-12-27 16:01:22)

Add getIn function
This PR adds a `getIn` function as requested in #149.


Patch:
diff --git a/README.md b/README.md
index 7af5b1d..e9f54e6 100644
--- a/README.md
+++ b/README.md
@@ -308,6 +308,18 @@ Immutable.setIn(obj, ["type", "sub"], "Norwegian Ridgeback");
 
 A second argument can be provided to perform a deep compare: `{deep: true}`.
 
+### getIn
+
+Returns the value at the given path. A default value can be provided as a second argument.
+
+```javascript
+var obj = Immutable({type: {main: "parrot", subtype: "Norwegian Blue"}, status: "alive"});
+Immutable.getIn(obj, ["type", "subtype"]);
+// returns "Norwegian Blue"
+Immutable.getIn(obj, ["type", "class"], "Aves");
+// returns "Aves"
+```
+
 ### update
 
 Returns an Immutable Object with a single property updated using the provided updater function.
diff --git a/seamless-immutable.development.js b/seamless-immutable.development.js
index 84e6f50..c68c571 100644
--- a/seamless-immutable.development.js
+++ b/seamless-immutable.development.js
@@ -203,6 +203,7 @@ function immutableInit(config) {
       addPropertyTo(array, "setIn", arraySetIn);
       addPropertyTo(array, "update", update);
       addPropertyTo(array, "updateIn", updateIn);
+      addPropertyTo(array, "getIn", getIn);
     }
 
     for(var i = 0, length = array.length; i < length; i++) {
@@ -551,6 +552,11 @@ function immutableInit(config) {
     return Immutable.setIn(this, path, updater.apply(initialVal, [initialVal].concat(restArgs)));
   }
 
+  function getIn(path, defaultValue) {
+    var value = getInPath(this, path);
+    return value === undefined ? defaultValue : value;
+  }
+
   function asMutableObject(opts) {
     var result = instantiateEmptyObject(this), key;
 
@@ -587,6 +593,7 @@ function immutableInit(config) {
       addPropertyTo(obj, "setIn", objectSetIn);
       addPropertyTo(obj, "update", update);
       addPropertyTo(obj, "updateIn", updateIn);
+      addPropertyTo(obj, "getIn", getIn);
     }
 
     return makeImmutable(obj, mutatingObjectMethods);
@@ -702,6 +709,7 @@ function immutableInit(config) {
   Immutable.setIn          = toStaticObjectOrArray(objectSetIn, arraySetIn);
   Immutable.update         = toStatic(update);
   Immutable.updateIn       = toStatic(updateIn);
+  Immutable.getIn          = toStatic(getIn);
   Immutable.flatMap        = toStatic(flatMap);
   Immutable.asObject       = toStatic(asObject);
   if (!globalConfig.use_static) {
diff --git a/seamless-immutable.development.min.js b/seamless-immutable.development.min.js
index 0d771f9..fd4585d 100644
--- a/seamless-immutable.development.min.js
+++ b/seamless-immutable.development.min.js
@@ -1,1 +1,1 @@
-/* (c) 2016, Richard Feldman, github.com/rtfeldman/seamless-immutable/blob/master/LICENSE */!function(){"use strict";function a(b){function c(a){return"object"==typeof a&&!Array.isArray(a)&&null!==a}function d(a){var b=Object.getPrototypeOf(a);return b?Object.create(b):{}}function e(a,b,c){Object.defineProperty(a,b,{enumerable:!1,configurable:!1,writable:!1,value:c})}function f(a,b){e(a,b,function(){throw new k("The "+b+" method cannot be invoked on an Immutable data structure.")})}function g(a){e(a,R,!0)}function h(a){return"object"!=typeof a||(null===a||Boolean(Object.getOwnPropertyDescriptor(a,R)))}function i(a,b){return a===b||a!==a&&b!==b}function j(a){return!(null===a||"object"!=typeof a||Array.isArray(a)||a instanceof Date)}function k(a){this.name="MyError",this.message=a,this.stack=(new Error).stack}function l(a,b){g(a);for(var c in b)b.hasOwnProperty(c)&&f(a,b[c]);return Object.freeze(a),a}function m(a,b){var c=a[b];e(a,b,function(){return K(c.apply(a,arguments))})}function n(a,b,c){var d=c&&c.deep;if(a in this&&(d&&this[a]!==b&&j(b)&&j(this[a])&&(b=K.merge(this[a],b,{deep:!0,mode:"replace"})),i(this[a],b)))return this;var e=u.call(this);return e[a]=K(b),p(e)}function o(a,b,c){var d=a[0];if(1===a.length)return n.call(this,d,b,c);var e,f=a.slice(1),g=this[d];if("object"==typeof g&&null!==g)e=K.setIn(g,f,b);else{var h=f[0];e=""!==h&&isFinite(h)?o.call(X,f,b):A.call(Y,f,b)}if(d in this&&g===e)return this;var i=u.call(this);return i[d]=e,p(i)}function p(a){for(var b in V)if(V.hasOwnProperty(b)){var c=V[b];m(a,c)}Q.use_static||(e(a,"flatMap",s),e(a,"asObject",v),e(a,"asMutable",u),e(a,"set",n),e(a,"setIn",o),e(a,"update",C),e(a,"updateIn",E));for(var d=0,f=a.length;d<f;d++)a[d]=K(a[d]);return l(a,U)}function q(a){return Q.use_static||e(a,"asMutable",r),l(a,W)}function r(){return new Date(this.getTime())}function s(a){if(0===arguments.length)return this;var b,c=[],d=this.length;for(b=0;b<d;b++){var e=a(this[b],b,this);Array.isArray(e)?c.push.apply(c,e):c.push(e)}return p(c)}function t(a){if("undefined"==typeof a&&0===arguments.length)return this;if("function"!=typeof a){var b=Array.isArray(a)?a.slice():Array.prototype.slice.call(arguments);b.forEach(function(a,b,c){"number"==typeof a&&(c[b]=a.toString())}),a=function(a,c){return b.indexOf(c)!==-1}}var c=d(this);for(var e in this)this.hasOwnProperty(e)&&a(this[e],e)===!1&&(c[e]=this[e]);return H(c)}function u(a){var b,c,d=[];if(a&&a.deep)for(b=0,c=this.length;b<c;b++)d.push(w(this[b]));else for(b=0,c=this.length;b<c;b++)d.push(this[b]);return d}function v(a){"function"!=typeof a&&(a=function(a){return a});var b,c={},d=this.length;for(b=0;b<d;b++){var e=a(this[b],b,this),f=e[0],g=e[1];c[f]=g}return H(c)}function w(a){return!a||"object"!=typeof a||!Object.getOwnPropertyDescriptor(a,R)||a instanceof Date?a:K.asMutable(a,{deep:!0})}function x(a,b){for(var c in a)Object.getOwnPropertyDescriptor(a,c)&&(b[c]=a[c]);return b}function y(a,b){function c(a,c,e){var g=K(c[e]),h=m&&m(a[e],g,b),l=a[e];if(void 0!==f||void 0!==h||!a.hasOwnProperty(e)||!i(g,l)){var n;n=h?h:k&&j(l)&&j(g)?K.merge(l,g,b):g,i(l,n)&&a.hasOwnProperty(e)||(void 0===f&&(f=x(a,d(a))),f[e]=n)}}function e(a,b){for(var c in a)b.hasOwnProperty(c)||(void 0===f&&(f=x(a,d(a))),delete f[c])}if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#merge can only be invoked with objects or arrays, not "+JSON.stringify(a));var f,g,h=Array.isArray(a),k=b&&b.deep,l=b&&b.mode||"merge",m=b&&b.merger;if(h)for(var n=0,o=a.length;n<o;n++){var p=a[n];for(g in p)p.hasOwnProperty(g)&&c(void 0!==f?f:this,p,g)}else{for(g in a)Object.getOwnPropertyDescriptor(a,g)&&c(this,a,g);"replace"===l&&e(this,a)}return void 0===f?this:H(f)}function z(a,b){var c=b&&b.deep;if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#replace can only be invoked with objects or arrays, not "+JSON.stringify(a));return K.merge(this,a,{deep:c,mode:"replace"})}function A(a,b,c){if(!(a instanceof Array)||0===a.length)throw new TypeError('The first argument to Immutable#setIn must be an array containing at least one "key" string.');var e=a[0];if(1===a.length)return B.call(this,e,b,c);var f,g=a.slice(1),h=this[e];if(f=this.hasOwnProperty(e)&&"object"==typeof h&&null!==h?K.setIn(h,g,b):A.call(Y,g,b),this.hasOwnProperty(e)&&h===f)return this;var i=x(this,d(this));return i[e]=f,H(i)}function B(a,b,c){var e=c&&c.deep;if(this.hasOwnProperty(a)&&(e&&this[a]!==b&&j(b)&&j(this[a])&&(b=K.merge(this[a],b,{deep:!0,mode:"replace"})),i(this[a],b)))return this;var f=x(this,d(this));return f[a]=K(b),H(f)}function C(a,b){var c=Array.prototype.slice.call(arguments,2),d=this[a];return K.set(this,a,b.apply(d,[d].concat(c)))}function D(a,b){for(var c=0,d=b.length;null!=a&&c<d;c++)a=a[b[c]];return c&&c==d?a:void 0}function E(a,b){var c=Array.prototype.slice.call(arguments,2),d=D(this,a);return K.setIn(this,a,b.apply(d,[d].concat(c)))}function F(a){var b,c=d(this);if(a&&a.deep)for(b in this)this.hasOwnProperty(b)&&(c[b]=w(this[b]));else for(b in this)this.hasOwnProperty(b)&&(c[b]=this[b]);return c}function G(){return{}}function H(a){return Q.use_static||(e(a,"merge",y),e(a,"replace",z),e(a,"without",t),e(a,"asMutable",F),e(a,"set",B),e(a,"setIn",A),e(a,"update",C),e(a,"updateIn",E)),l(a,S)}function I(a){return"object"==typeof a&&null!==a&&(a.$$typeof===P||a.$$typeof===O)}function J(a){return"undefined"!=typeof File&&a instanceof File}function K(a,b,c){if(h(a)||I(a)||J(a))return a;if(Array.isArray(a))return p(a.slice());if(a instanceof Date)return q(new Date(a.getTime()));var d=b&&b.prototype,e=d&&d!==Object.prototype?function(){return Object.create(d)}:G,f=e();if(null==c&&(c=64),c<=0)throw new k("Attempt to construct Immutable from a deeply nested object was detected. Have you tried to wrap an object with circular references (e.g. React element)? See https://github.com/rtfeldman/seamless-immutable/wiki/Deeply-nested-object-was-detected for details.");c-=1;for(var g in a)Object.getOwnPropertyDescriptor(a,g)&&(f[g]=K(a[g],void 0,c));return H(f)}function L(a){function b(){var b=[].slice.call(arguments),c=b.shift();return a.apply(c,b)}return b}function M(a,b){function c(){var c=[].slice.call(arguments),d=c.shift();return Array.isArray(d)?b.apply(d,c):a.apply(d,c)}return c}function N(a,b,c){function d(){var d=[].slice.call(arguments),e=d.shift();return Array.isArray(e)?b.apply(e,d):e instanceof Date?c.apply(e,d):a.apply(e,d)}return d}var O="function"==typeof Symbol&&Symbol["for"]&&Symbol["for"]("react.element"),P=60103,Q={use_static:!1};c(b)&&void 0!==b.use_static&&(Q.use_static=Boolean(b.use_static));var R="__immutable_invariants_hold",S=["setPrototypeOf"],T=["keys"],U=S.concat(["push","pop","sort","splice","shift","unshift","reverse"]),V=T.concat(["map","filter","slice","concat","reduce","reduceRight"]),W=S.concat(["setDate","setFullYear","setHours","setMilliseconds","setMinutes","setMonth","setSeconds","setTime","setUTCDate","setUTCFullYear","setUTCHours","setUTCMilliseconds","setUTCMinutes","setUTCMonth","setUTCSeconds","setYear"]);k.prototype=new Error,k.prototype.constructor=Error;var X=K([]),Y=K({});return K.from=K,K.isImmutable=h,K.ImmutableError=k,K.merge=L(y),K.replace=L(z),K.without=L(t),K.asMutable=N(F,u,r),K.set=M(B,n),K.setIn=M(A,o),K.update=L(C),K.updateIn=L(E),K.flatMap=L(s),K.asObject=L(v),Q.use_static||(K["static"]=a({use_static:!0})),Object.freeze(K),K}var b=a();"function"==typeof define&&define.amd?define(function(){return b}):"object"==typeof module?module.exports=b:"object"==typeof exports?exports.Immutable=b:"object"==typeof window?window.Immutable=b:"object"==typeof global&&(global.Immutable=b)}();
\ No newline at end of file
+/* (c) 2016, Richard Feldman, github.com/rtfeldman/seamless-immutable/blob/master/LICENSE */!function(){"use strict";function a(b){function c(a){return"object"==typeof a&&!Array.isArray(a)&&null!==a}function d(a){var b=Object.getPrototypeOf(a);return b?Object.create(b):{}}function e(a,b,c){Object.defineProperty(a,b,{enumerable:!1,configurable:!1,writable:!1,value:c})}function f(a,b){e(a,b,function(){throw new k("The "+b+" method cannot be invoked on an Immutable data structure.")})}function g(a){e(a,S,!0)}function h(a){return"object"!=typeof a||(null===a||Boolean(Object.getOwnPropertyDescriptor(a,S)))}function i(a,b){return a===b||a!==a&&b!==b}function j(a){return!(null===a||"object"!=typeof a||Array.isArray(a)||a instanceof Date)}function k(a){var b=new Error(a);return b.__proto__=k,b}function l(a,b){g(a);for(var c in b)b.hasOwnProperty(c)&&f(a,b[c]);return Object.freeze(a),a}function m(a,b){var c=a[b];e(a,b,function(){return L(c.apply(a,arguments))})}function n(a,b,c){var d=c&&c.deep;if(a in this&&(d&&this[a]!==b&&j(b)&&j(this[a])&&(b=L.merge(this[a],b,{deep:!0,mode:"replace"})),i(this[a],b)))return this;var e=u.call(this);return e[a]=L(b),p(e)}function o(a,b,c){var d=a[0];if(1===a.length)return n.call(this,d,b,c);var e,f=a.slice(1),g=this[d];if("object"==typeof g&&null!==g)e=L.setIn(g,f,b);else{var h=f[0];e=""!==h&&isFinite(h)?o.call(Y,f,b):A.call(Z,f,b)}if(d in this&&g===e)return this;var i=u.call(this);return i[d]=e,p(i)}function p(a){for(var b in W)if(W.hasOwnProperty(b)){var c=W[b];m(a,c)}R.use_static||(e(a,"flatMap",s),e(a,"asObject",v),e(a,"asMutable",u),e(a,"set",n),e(a,"setIn",o),e(a,"update",C),e(a,"updateIn",E),e(a,"getIn",F));for(var d=0,f=a.length;d<f;d++)a[d]=L(a[d]);return l(a,V)}function q(a){return R.use_static||e(a,"asMutable",r),l(a,X)}function r(){return new Date(this.getTime())}function s(a){if(0===arguments.length)return this;var b,c=[],d=this.length;for(b=0;b<d;b++){var e=a(this[b],b,this);Array.isArray(e)?c.push.apply(c,e):c.push(e)}return p(c)}function t(a){if("undefined"==typeof a&&0===arguments.length)return this;if("function"!=typeof a){var b=Array.isArray(a)?a.slice():Array.prototype.slice.call(arguments);b.forEach(function(a,b,c){"number"==typeof a&&(c[b]=a.toString())}),a=function(a,c){return b.indexOf(c)!==-1}}var c=d(this);for(var e in this)this.hasOwnProperty(e)&&a(this[e],e)===!1&&(c[e]=this[e]);return I(c)}function u(a){var b,c,d=[];if(a&&a.deep)for(b=0,c=this.length;b<c;b++)d.push(w(this[b]));else for(b=0,c=this.length;b<c;b++)d.push(this[b]);return d}function v(a){"function"!=typeof a&&(a=function(a){return a});var b,c={},d=this.length;for(b=0;b<d;b++){var e=a(this[b],b,this),f=e[0],g=e[1];c[f]=g}return I(c)}function w(a){return!a||"object"!=typeof a||!Object.getOwnPropertyDescriptor(a,S)||a instanceof Date?a:L.asMutable(a,{deep:!0})}function x(a,b){for(var c in a)Object.getOwnPropertyDescriptor(a,c)&&(b[c]=a[c]);return b}function y(a,b){function c(a,c,e){var g=L(c[e]),h=m&&m(a[e],g,b),l=a[e];if(void 0!==f||void 0!==h||!a.hasOwnProperty(e)||!i(g,l)){var n;n=h?h:k&&j(l)&&j(g)?L.merge(l,g,b):g,i(l,n)&&a.hasOwnProperty(e)||(void 0===f&&(f=x(a,d(a))),f[e]=n)}}function e(a,b){for(var c in a)b.hasOwnProperty(c)||(void 0===f&&(f=x(a,d(a))),delete f[c])}if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#merge can only be invoked with objects or arrays, not "+JSON.stringify(a));var f,g,h=Array.isArray(a),k=b&&b.deep,l=b&&b.mode||"merge",m=b&&b.merger;if(h)for(var n=0,o=a.length;n<o;n++){var p=a[n];for(g in p)p.hasOwnProperty(g)&&c(void 0!==f?f:this,p,g)}else{for(g in a)Object.getOwnPropertyDescriptor(a,g)&&c(this,a,g);"replace"===l&&e(this,a)}return void 0===f?this:I(f)}function z(a,b){var c=b&&b.deep;if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#replace can only be invoked with objects or arrays, not "+JSON.stringify(a));return L.merge(this,a,{deep:c,mode:"replace"})}function A(a,b,c){if(!(a instanceof Array)||0===a.length)throw new TypeError('The first argument to Immutable#setIn must be an array containing at least one "key" string.');var e=a[0];if(1===a.length)return B.call(this,e,b,c);var f,g=a.slice(1),h=this[e];if(f=this.hasOwnProperty(e)&&"object"==typeof h&&null!==h?L.setIn(h,g,b):A.call(Z,g,b),this.hasOwnProperty(e)&&h===f)return this;var i=x(this,d(this));return i[e]=f,I(i)}function B(a,b,c){var e=c&&c.deep;if(this.hasOwnProperty(a)&&(e&&this[a]!==b&&j(b)&&j(this[a])&&(b=L.merge(this[a],b,{deep:!0,mode:"replace"})),i(this[a],b)))return this;var f=x(this,d(this));return f[a]=L(b),I(f)}function C(a,b){var c=Array.prototype.slice.call(arguments,2),d=this[a];return L.set(this,a,b.apply(d,[d].concat(c)))}function D(a,b){for(var c=0,d=b.length;null!=a&&c<d;c++)a=a[b[c]];return c&&c==d?a:void 0}function E(a,b){var c=Array.prototype.slice.call(arguments,2),d=D(this,a);return L.setIn(this,a,b.apply(d,[d].concat(c)))}function F(a,b){var c=D(this,a);return void 0===c?b:c}function G(a){var b,c=d(this);if(a&&a.deep)for(b in this)this.hasOwnProperty(b)&&(c[b]=w(this[b]));else for(b in this)this.hasOwnProperty(b)&&(c[b]=this[b]);return c}function H(){return{}}function I(a){return R.use_static||(e(a,"merge",y),e(a,"replace",z),e(a,"without",t),e(a,"asMutable",G),e(a,"set",B),e(a,"setIn",A),e(a,"update",C),e(a,"updateIn",E),e(a,"getIn",F)),l(a,T)}function J(a){return"object"==typeof a&&null!==a&&(a.$$typeof===Q||a.$$typeof===P)}function K(a){return"undefined"!=typeof File&&a instanceof File}function L(a,b,c){if(h(a)||J(a)||K(a))return a;if(Array.isArray(a))return p(a.slice());if(a instanceof Date)return q(new Date(a.getTime()));var d=b&&b.prototype,e=d&&d!==Object.prototype?function(){return Object.create(d)}:H,f=e();if(null==c&&(c=64),c<=0)throw new k("Attempt to construct Immutable from a deeply nested object was detected. Have you tried to wrap an object with circular references (e.g. React element)? See https://github.com/rtfeldman/seamless-immutable/wiki/Deeply-nested-object-was-detected for details.");c-=1;for(var g in a)Object.getOwnPropertyDescriptor(a,g)&&(f[g]=L(a[g],void 0,c));return I(f)}function M(a){function b(){var b=[].slice.call(arguments),c=b.shift();return a.apply(c,b)}return b}function N(a,b){function c(){var c=[].slice.call(arguments),d=c.shift();return Array.isArray(d)?b.apply(d,c):a.apply(d,c)}return c}function O(a,b,c){function d(){var d=[].slice.call(arguments),e=d.shift();return Array.isArray(e)?b.apply(e,d):e instanceof Date?c.apply(e,d):a.apply(e,d)}return d}var P="function"==typeof Symbol&&Symbol["for"]&&Symbol["for"]("react.element"),Q=60103,R={use_static:!1};c(b)&&void 0!==b.use_static&&(R.use_static=Boolean(b.use_static));var S="__immutable_invariants_hold",T=["setPrototypeOf"],U=["keys"],V=T.concat(["push","pop","sort","splice","shift","unshift","reverse"]),W=U.concat(["map","filter","slice","concat","reduce","reduceRight"]),X=T.concat(["setDate","setFullYear","setHours","setMilliseconds","setMinutes","setMonth","setSeconds","setTime","setUTCDate","setUTCFullYear","setUTCHours","setUTCMilliseconds","setUTCMinutes","setUTCMonth","setUTCSeconds","setYear"]);k.prototype=Error.prototype;var Y=L([]),Z=L({});return L.from=L,L.isImmutable=h,L.ImmutableError=k,L.merge=M(y),L.replace=M(z),L.without=M(t),L.asMutable=O(G,u,r),L.set=N(B,n),L.setIn=N(A,o),L.update=M(C),L.updateIn=M(E),L.getIn=M(F),L.flatMap=M(s),L.asObject=M(v),R.use_static||(L["static"]=a({use_static:!0})),Object.freeze(L),L}var b=a();"function"==typeof define&&define.amd?define(function(){return b}):"object"==typeof module?module.exports=b:"object"==typeof exports?exports.Immutable=b:"object"==typeof window?window.Immutable=b:"object"==typeof global&&(global.Immutable=b)}();
diff --git a/seamless-immutable.production.min.js b/seamless-immutable.production.min.js
index 9f70195..be1eaad 100644
--- a/seamless-immutable.production.min.js
+++ b/seamless-immutable.production.min.js
@@ -1,1 +1,1 @@
-/* (c) 2016, Richard Feldman, github.com/rtfeldman/seamless-immutable/blob/master/LICENSE */!function(){"use strict";function a(b){function c(a){return"object"==typeof a&&!Array.isArray(a)&&null!==a}function d(a){var b=Object.getPrototypeOf(a);return b?Object.create(b):{}}function e(a,b,c){Object.defineProperty(a,b,{enumerable:!1,configurable:!1,writable:!1,value:c})}function f(a){e(a,Q,!0)}function g(a){return"object"!=typeof a||(null===a||Boolean(Object.getOwnPropertyDescriptor(a,Q)))}function h(a,b){return a===b||a!==a&&b!==b}function i(a){return!(null===a||"object"!=typeof a||Array.isArray(a)||a instanceof Date)}function j(a){this.name="MyError",this.message=a,this.stack=(new Error).stack}function k(a,b){f(a);return a}function l(a,b){var c=a[b];e(a,b,function(){return J(c.apply(a,arguments))})}function m(a,b,c){var d=c&&c.deep;if(a in this&&(d&&this[a]!==b&&i(b)&&i(this[a])&&(b=J.merge(this[a],b,{deep:!0,mode:"replace"})),h(this[a],b)))return this;var e=t.call(this);return e[a]=J(b),o(e)}function n(a,b,c){var d=a[0];if(1===a.length)return m.call(this,d,b,c);var e,f=a.slice(1),g=this[d];if("object"==typeof g&&null!==g)e=J.setIn(g,f,b);else{var h=f[0];e=""!==h&&isFinite(h)?n.call(W,f,b):z.call(X,f,b)}if(d in this&&g===e)return this;var i=t.call(this);return i[d]=e,o(i)}function o(a){for(var b in U)if(U.hasOwnProperty(b)){var c=U[b];l(a,c)}P.use_static||(e(a,"flatMap",r),e(a,"asObject",u),e(a,"asMutable",t),e(a,"set",m),e(a,"setIn",n),e(a,"update",B),e(a,"updateIn",D));for(var d=0,f=a.length;d<f;d++)a[d]=J(a[d]);return k(a,T)}function p(a){return P.use_static||e(a,"asMutable",q),k(a,V)}function q(){return new Date(this.getTime())}function r(a){if(0===arguments.length)return this;var b,c=[],d=this.length;for(b=0;b<d;b++){var e=a(this[b],b,this);Array.isArray(e)?c.push.apply(c,e):c.push(e)}return o(c)}function s(a){if("undefined"==typeof a&&0===arguments.length)return this;if("function"!=typeof a){var b=Array.isArray(a)?a.slice():Array.prototype.slice.call(arguments);b.forEach(function(a,b,c){"number"==typeof a&&(c[b]=a.toString())}),a=function(a,c){return b.indexOf(c)!==-1}}var c=d(this);for(var e in this)this.hasOwnProperty(e)&&a(this[e],e)===!1&&(c[e]=this[e]);return G(c)}function t(a){var b,c,d=[];if(a&&a.deep)for(b=0,c=this.length;b<c;b++)d.push(v(this[b]));else for(b=0,c=this.length;b<c;b++)d.push(this[b]);return d}function u(a){"function"!=typeof a&&(a=function(a){return a});var b,c={},d=this.length;for(b=0;b<d;b++){var e=a(this[b],b,this),f=e[0],g=e[1];c[f]=g}return G(c)}function v(a){return!a||"object"!=typeof a||!Object.getOwnPropertyDescriptor(a,Q)||a instanceof Date?a:J.asMutable(a,{deep:!0})}function w(a,b){for(var c in a)Object.getOwnPropertyDescriptor(a,c)&&(b[c]=a[c]);return b}function x(a,b){function c(a,c,e){var g=J(c[e]),j=m&&m(a[e],g,b),l=a[e];if(void 0!==f||void 0!==j||!a.hasOwnProperty(e)||!h(g,l)){var n;n=j?j:k&&i(l)&&i(g)?J.merge(l,g,b):g,h(l,n)&&a.hasOwnProperty(e)||(void 0===f&&(f=w(a,d(a))),f[e]=n)}}function e(a,b){for(var c in a)b.hasOwnProperty(c)||(void 0===f&&(f=w(a,d(a))),delete f[c])}if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#merge can only be invoked with objects or arrays, not "+JSON.stringify(a));var f,g,j=Array.isArray(a),k=b&&b.deep,l=b&&b.mode||"merge",m=b&&b.merger;if(j)for(var n=0,o=a.length;n<o;n++){var p=a[n];for(g in p)p.hasOwnProperty(g)&&c(void 0!==f?f:this,p,g)}else{for(g in a)Object.getOwnPropertyDescriptor(a,g)&&c(this,a,g);"replace"===l&&e(this,a)}return void 0===f?this:G(f)}function y(a,b){var c=b&&b.deep;if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#replace can only be invoked with objects or arrays, not "+JSON.stringify(a));return J.merge(this,a,{deep:c,mode:"replace"})}function z(a,b,c){if(!(a instanceof Array)||0===a.length)throw new TypeError('The first argument to Immutable#setIn must be an array containing at least one "key" string.');var e=a[0];if(1===a.length)return A.call(this,e,b,c);var f,g=a.slice(1),h=this[e];if(f=this.hasOwnProperty(e)&&"object"==typeof h&&null!==h?J.setIn(h,g,b):z.call(X,g,b),this.hasOwnProperty(e)&&h===f)return this;var i=w(this,d(this));return i[e]=f,G(i)}function A(a,b,c){var e=c&&c.deep;if(this.hasOwnProperty(a)&&(e&&this[a]!==b&&i(b)&&i(this[a])&&(b=J.merge(this[a],b,{deep:!0,mode:"replace"})),h(this[a],b)))return this;var f=w(this,d(this));return f[a]=J(b),G(f)}function B(a,b){var c=Array.prototype.slice.call(arguments,2),d=this[a];return J.set(this,a,b.apply(d,[d].concat(c)))}function C(a,b){for(var c=0,d=b.length;null!=a&&c<d;c++)a=a[b[c]];return c&&c==d?a:void 0}function D(a,b){var c=Array.prototype.slice.call(arguments,2),d=C(this,a);return J.setIn(this,a,b.apply(d,[d].concat(c)))}function E(a){var b,c=d(this);if(a&&a.deep)for(b in this)this.hasOwnProperty(b)&&(c[b]=v(this[b]));else for(b in this)this.hasOwnProperty(b)&&(c[b]=this[b]);return c}function F(){return{}}function G(a){return P.use_static||(e(a,"merge",x),e(a,"replace",y),e(a,"without",s),e(a,"asMutable",E),e(a,"set",A),e(a,"setIn",z),e(a,"update",B),e(a,"updateIn",D)),k(a,R)}function H(a){return"object"==typeof a&&null!==a&&(a.$$typeof===O||a.$$typeof===N)}function I(a){return"undefined"!=typeof File&&a instanceof File}function J(a,b,c){if(g(a)||H(a)||I(a))return a;if(Array.isArray(a))return o(a.slice());if(a instanceof Date)return p(new Date(a.getTime()));var d=b&&b.prototype,e=d&&d!==Object.prototype?function(){return Object.create(d)}:F,f=e();for(var h in a)Object.getOwnPropertyDescriptor(a,h)&&(f[h]=J(a[h],void 0,c));return G(f)}function K(a){function b(){var b=[].slice.call(arguments),c=b.shift();return a.apply(c,b)}return b}function L(a,b){function c(){var c=[].slice.call(arguments),d=c.shift();return Array.isArray(d)?b.apply(d,c):a.apply(d,c)}return c}function M(a,b,c){function d(){var d=[].slice.call(arguments),e=d.shift();return Array.isArray(e)?b.apply(e,d):e instanceof Date?c.apply(e,d):a.apply(e,d)}return d}var N="function"==typeof Symbol&&Symbol["for"]&&Symbol["for"]("react.element"),O=60103,P={use_static:!1};c(b)&&void 0!==b.use_static&&(P.use_static=Boolean(b.use_static));var Q="__immutable_invariants_hold",R=["setPrototypeOf"],S=["keys"],T=R.concat(["push","pop","sort","splice","shift","unshift","reverse"]),U=S.concat(["map","filter","slice","concat","reduce","reduceRight"]),V=R.concat(["setDate","setFullYear","setHours","setMilliseconds","setMinutes","setMonth","setSeconds","setTime","setUTCDate","setUTCFullYear","setUTCHours","setUTCMilliseconds","setUTCMinutes","setUTCMonth","setUTCSeconds","setYear"]);j.prototype=new Error,j.prototype.constructor=Error;var W=J([]),X=J({});return J.from=J,J.isImmutable=g,J.ImmutableError=j,J.merge=K(x),J.replace=K(y),J.without=K(s),J.asMutable=M(E,t,q),J.set=L(A,m),J.setIn=L(z,n),J.update=K(B),J.updateIn=K(D),J.flatMap=K(r),J.asObject=K(u),P.use_static||(J["static"]=a({use_static:!0})),Object.freeze(J),J}var b=a();"function"==typeof define&&define.amd?define(function(){return b}):"object"==typeof module?module.exports=b:"object"==typeof exports?exports.Immutable=b:"object"==typeof window?window.Immutable=b:"object"==typeof global&&(global.Immutable=b)}();
\ No newline at end of file
+/* (c) 2016, Richard Feldman, github.com/rtfeldman/seamless-immutable/blob/master/LICENSE */!function(){"use strict";function a(b){function c(a){return"object"==typeof a&&!Array.isArray(a)&&null!==a}function d(a){var b=Object.getPrototypeOf(a);return b?Object.create(b):{}}function e(a,b,c){Object.defineProperty(a,b,{enumerable:!1,configurable:!1,writable:!1,value:c})}function f(a){e(a,Q,!0)}function g(a){return"object"!=typeof a||(null===a||Boolean(Object.getOwnPropertyDescriptor(a,Q)))}function h(a,b){return a===b||a!==a&&b!==b}function i(a){return!(null===a||"object"!=typeof a||Array.isArray(a)||a instanceof Date)}function j(a){this.name="MyError",this.message=a,this.stack=(new Error).stack}function k(a,b){f(a);return a}function l(a,b){var c=a[b];e(a,b,function(){return J(c.apply(a,arguments))})}function m(a,b,c){var d=c&&c.deep;if(a in this&&(d&&this[a]!==b&&i(b)&&i(this[a])&&(b=J.merge(this[a],b,{deep:!0,mode:"replace"})),h(this[a],b)))return this;var e=t.call(this);return e[a]=J(b),o(e)}function n(a,b,c){var d=a[0];if(1===a.length)return m.call(this,d,b,c);var e,f=a.slice(1),g=this[d];if("object"==typeof g&&null!==g)e=J.setIn(g,f,b);else{var h=f[0];e=""!==h&&isFinite(h)?n.call(W,f,b):z.call(X,f,b)}if(d in this&&g===e)return this;var i=t.call(this);return i[d]=e,o(i)}function o(a){for(var b in U)if(U.hasOwnProperty(b)){var c=U[b];l(a,c)}P.use_static||(e(a,"flatMap",r),e(a,"asObject",u),e(a,"asMutable",t),e(a,"set",m),e(a,"setIn",n),e(a,"update",B),e(a,"updateIn",D));for(var d=0,f=a.length;d<f;d++)a[d]=J(a[d]);return k(a,T)}function p(a){return P.use_static||e(a,"asMutable",q),k(a,V)}function q(){return new Date(this.getTime())}function r(a){if(0===arguments.length)return this;var b,c=[],d=this.length;for(b=0;b<d;b++){var e=a(this[b],b,this);Array.isArray(e)?c.push.apply(c,e):c.push(e)}return o(c)}function s(a){if("undefined"==typeof a&&0===arguments.length)return this;if("function"!=typeof a){var b=Array.isArray(a)?a.slice():Array.prototype.slice.call(arguments);b.forEach(function(a,b,c){"number"==typeof a&&(c[b]=a.toString())}),a=function(a,c){return b.indexOf(c)!==-1}}var c=d(this);for(var e in this)this.hasOwnProperty(e)&&a(this[e],e)===!1&&(c[e]=this[e]);return G(c)}function t(a){var b,c,d=[];if(a&&a.deep)for(b=0,c=this.length;b<c;b++)d.push(v(this[b]));else for(b=0,c=this.length;b<c;b++)d.push(this[b]);return d}function u(a){"function"!=typeof a&&(a=function(a){return a});var b,c={},d=this.length;for(b=0;b<d;b++){var e=a(this[b],b,this),f=e[0],g=e[1];c[f]=g}return G(c)}function v(a){return!a||"object"!=typeof a||!Object.getOwnPropertyDescriptor(a,Q)||a instanceof Date?a:J.asMutable(a,{deep:!0})}function w(a,b){for(var c in a)Object.getOwnPropertyDescriptor(a,c)&&(b[c]=a[c]);return b}function x(a,b){function c(a,c,e){var g=J(c[e]),j=m&&m(a[e],g,b),l=a[e];if(void 0!==f||void 0!==j||!a.hasOwnProperty(e)||!h(g,l)){var n;n=j?j:k&&i(l)&&i(g)?J.merge(l,g,b):g,h(l,n)&&a.hasOwnProperty(e)||(void 0===f&&(f=w(a,d(a))),f[e]=n)}}function e(a,b){for(var c in a)b.hasOwnProperty(c)||(void 0===f&&(f=w(a,d(a))),delete f[c])}if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#merge can only be invoked with objects or arrays, not "+JSON.stringify(a));var f,g,j=Array.isArray(a),k=b&&b.deep,l=b&&b.mode||"merge",m=b&&b.merger;if(j)for(var n=0,o=a.length;n<o;n++){var p=a[n];for(g in p)p.hasOwnProperty(g)&&c(void 0!==f?f:this,p,g)}else{for(g in a)Object.getOwnPropertyDescriptor(a,g)&&c(this,a,g);"replace"===l&&e(this,a)}return void 0===f?this:G(f)}function y(a,b){var c=b&&b.deep;if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#replace can only be invoked with objects or arrays, not "+JSON.stringify(a));return J.merge(this,a,{deep:c,mode:"replace"})}function z(a,b,c){if(!(a instanceof Array)||0===a.length)throw new TypeError('The first argument to Immutable#setIn must be an array containing at least one "key" string.');var e=a[0];if(1===a.length)return A.call(this,e,b,c);var f,g=a.slice(1),h=this[e];if(f=this.hasOwnProperty(e)&&"object"==typeof h&&null!==h?J.setIn(h,g,b):z.call(X,g,b),this.hasOwnProperty(e)&&h===f)return this;var i=w(this,d(this));return i[e]=f,G(i)}function A(a,b,c){var e=c&&c.deep;if(this.hasOwnProperty(a)&&(e&&this[a]!==b&&i(b)&&i(this[a])&&(b=J.merge(this[a],b,{deep:!0,mode:"replace"})),h(this[a],b)))return this;var f=w(this,d(this));return f[a]=J(b),G(f)}function B(a,b){var c=Array.prototype.slice.call(arguments,2),d=this[a];return J.set(this,a,b.apply(d,[d].concat(c)))}function C(a,b){for(var c=0,d=b.length;null!=a&&c<d;c++)a=a[b[c]];return c&&c==d?a:void 0}function D(a,b){var c=Array.prototype.slice.call(arguments,2),d=C(this,a);return J.setIn(this,a,b.apply(d,[d].concat(c)))}function E(a){var b,c=d(this);if(a&&a.deep)for(b in this)this.hasOwnProperty(b)&&(c[b]=v(this[b]));else for(b in this)this.hasOwnProperty(b)&&(c[b]=this[b]);return c}function F(){return{}}function G(a){return P.use_static||(e(a,"merge",x),e(a,"replace",y),e(a,"without",s),e(a,"asMutable",E),e(a,"set",A),e(a,"setIn",z),e(a,"update",B),e(a,"updateIn",D)),k(a,R)}function H(a){return"object"==typeof a&&null!==a&&(a.$$typeof===O||a.$$typeof===N)}function I(a){return"undefined"!=typeof File&&a instanceof File}function J(a,b,c){if(g(a)||H(a)||I(a))return a;if(Array.isArray(a))return o(a.slice());if(a instanceof Date)return p(new Date(a.getTime()));var d=b&&b.prototype,e=d&&d!==Object.prototype?function(){return Object.create(d)}:F,f=e();for(var h in a)Object.getOwnPropertyDescriptor(a,h)&&(f[h]=J(a[h],void 0,c));return G(f)}function K(a){function b(){var b=[].slice.call(arguments),c=b.shift();return a.apply(c,b)}return b}function L(a,b){function c(){var c=[].slice.call(arguments),d=c.shift();return Array.isArray(d)?b.apply(d,c):a.apply(d,c)}return c}function M(a,b,c){function d(){var d=[].slice.call(arguments),e=d.shift();return Array.isArray(e)?b.apply(e,d):e instanceof Date?c.apply(e,d):a.apply(e,d)}return d}var N="function"==typeof Symbol&&Symbol["for"]&&Symbol["for"]("react.element"),O=60103,P={use_static:!1};c(b)&&void 0!==b.use_static&&(P.use_static=Boolean(b.use_static));var Q="__immutable_invariants_hold",R=["setPrototypeOf"],S=["keys"],T=R.concat(["push","pop","sort","splice","shift","unshift","reverse"]),U=S.concat(["map","filter","slice","concat","reduce","reduceRight"]),V=R.concat(["setDate","setFullYear","setHours","setMilliseconds","setMinutes","setMonth","setSeconds","setTime","setUTCDate","setUTCFullYear","setUTCHours","setUTCMilliseconds","setUTCMinutes","setUTCMonth","setUTCSeconds","setYear"]);j.prototype=new Error,j.prototype.constructor=Error;var W=J([]),X=J({});return J.from=J,J.isImmutable=g,J.ImmutableError=j,J.merge=K(x),J.replace=K(y),J.without=K(s),J.asMutable=M(E,t,q),J.set=L(A,m),J.setIn=L(z,n),J.update=K(B),J.updateIn=K(D),J.flatMap=K(r),J.asObject=K(u),P.use_static||(J["static"]=a({use_static:!0})),Object.freeze(J),J}var b=a();"function"==typeof define&&define.amd?define(function(){return b}):"object"==typeof module?module.exports=b:"object"==typeof exports?exports.Immutable=b:"object"==typeof window?window.Immutable=b:"object"==typeof global&&(global.Immutable=b)}();
diff --git a/src/seamless-immutable.js b/src/seamless-immutable.js
index ad17933..1de54d9 100644
--- a/src/seamless-immutable.js
+++ b/src/seamless-immutable.js
@@ -203,6 +203,7 @@ function immutableInit(config) {
       addPropertyTo(array, "setIn", arraySetIn);
       addPropertyTo(array, "update", update);
       addPropertyTo(array, "updateIn", updateIn);
+      addPropertyTo(array, "getIn", getIn);
     }
 
     for(var i = 0, length = array.length; i < length; i++) {
@@ -551,6 +552,11 @@ function immutableInit(config) {
     return Immutable.setIn(this, path, updater.apply(initialVal, [initialVal].concat(restArgs)));
   }
 
+  function getIn(path, defaultValue) {
+    var value = getInPath(this, path);
+    return value === undefined ? defaultValue : value;
+  }
+
   function asMutableObject(opts) {
     var result = instantiateEmptyObject(this), key;
 
@@ -587,6 +593,7 @@ function immutableInit(config) {
       addPropertyTo(obj, "setIn", objectSetIn);
       addPropertyTo(obj, "update", update);
       addPropertyTo(obj, "updateIn", updateIn);
+      addPropertyTo(obj, "getIn", getIn);
     }
 
     return makeImmutable(obj, mutatingObjectMethods);
@@ -702,6 +709,7 @@ function immutableInit(config) {
   Immutable.setIn          = toStaticObjectOrArray(objectSetIn, arraySetIn);
   Immutable.update         = toStatic(update);
   Immutable.updateIn       = toStatic(updateIn);
+  Immutable.getIn          = toStatic(getIn);
   Immutable.flatMap        = toStatic(flatMap);
   Immutable.asObject       = toStatic(asObject);
   if (!globalConfig.use_static) {


Test patch:
diff --git a/test/ImmutableArray.spec.js b/test/ImmutableArray.spec.js
index 716306d..8518aa0 100644
--- a/test/ImmutableArray.spec.js
+++ b/test/ImmutableArray.spec.js
@@ -4,6 +4,7 @@ var testAsObject  = require("./ImmutableArray/test-asObject.js");
 var testAsMutable = require("./ImmutableArray/test-asMutable.js");
 var testSet       = require("./ImmutableArray/test-set.js");
 var testUpdate    = require("./ImmutableArray/test-update.js");
+var testGetIn    = require("./ImmutableArray/test-getIn.js");
 var devBuild      = require("../seamless-immutable.development.js");
 var prodBuild     = require("../seamless-immutable.production.min.js");
 var getTestUtils  = require("./TestUtils.js");
@@ -23,6 +24,7 @@ var getTestUtils  = require("./TestUtils.js");
       testAsMutable(config);
       testSet(config);
       testUpdate(config);
+      testGetIn(config);
     });
   });
 });
diff --git a/test/ImmutableArray/test-getIn.js b/test/ImmutableArray/test-getIn.js
new file mode 100644
index 0000000..ae77432
--- /dev/null
+++ b/test/ImmutableArray/test-getIn.js
@@ -0,0 +1,45 @@
+var JSC          = require("jscheck");
+var _            = require("lodash");
+var getTestUtils = require("../TestUtils.js");
+
+
+module.exports = function(config) {
+  var Immutable = config.implementation;
+  var TestUtils = getTestUtils(Immutable);
+  var check     = TestUtils.check;
+
+  describe("#getIn", function() {
+    it("gets a property by path", function () {
+      check(100, [ JSC.array([TestUtils.TraversableObjectSpecifier]) ], function(array) {
+        var immutable = Immutable(array);
+        var idx = JSC.integer(0, array.length-1);
+        var key = JSC.one_of(_.keys(immutable[idx]))();
+        var value = immutable[idx][key];
+
+        TestUtils.assertJsonEqual(
+          Immutable.getIn(immutable, [idx, key]),
+          value
+        );
+      });
+    });
+
+    it("returns the default value if the resolved value is undefined", function () {
+      check(100, [TestUtils.ComplexObjectSpecifier()], function(ob) {
+        var immutable = Immutable([0,1,2]);
+
+        TestUtils.assertJsonEqual(
+          Immutable.getIn(immutable, [3], 'default'),
+          'default'
+        );
+      });
+    });
+
+    it("supports non-static syntax", function() {
+      var obj = Immutable(['test']);
+      obj = obj.getIn([0]);
+      TestUtils.assertJsonEqual(obj, 'test');
+    });
+  });
+};
+
+
diff --git a/test/ImmutableObject.spec.js b/test/ImmutableObject.spec.js
index 9dccd1d..f65ef88 100644
--- a/test/ImmutableObject.spec.js
+++ b/test/ImmutableObject.spec.js
@@ -5,6 +5,7 @@ var testWithout   = require("./ImmutableObject/test-without.js");
 var testAsMutable = require("./ImmutableObject/test-asMutable.js");
 var testSet       = require("./ImmutableObject/test-set.js");
 var testUpdate    = require("./ImmutableObject/test-update.js");
+var testGetIn    = require("./ImmutableObject/test-getIn.js");
 var devBuild      = require("../seamless-immutable.development.js");
 var prodBuild     = require("../seamless-immutable.production.min.js");
 var getTestUtils  = require("./TestUtils.js");
@@ -25,6 +26,7 @@ var getTestUtils  = require("./TestUtils.js");
       testAsMutable(config);
       testSet(config);
       testUpdate(config);
+      testGetIn(config);
     });
   });
 });
diff --git a/test/ImmutableObject/test-getIn.js b/test/ImmutableObject/test-getIn.js
new file mode 100644
index 0000000..d62b601
--- /dev/null
+++ b/test/ImmutableObject/test-getIn.js
@@ -0,0 +1,64 @@
+var JSC          = require("jscheck");
+var assert       = require("chai").assert;
+var _            = require("lodash");
+var getTestUtils = require("../TestUtils.js");
+
+
+module.exports = function(config) {
+  var Immutable = config.implementation;
+  var TestUtils = getTestUtils(Immutable);
+  var check     = TestUtils.check;
+
+  function getPathComponent() {
+    // It's very convenient to use lodash.set, but it has funky behaviour
+    // with numeric keys.
+    var s = JSC.string()().replace(/[^\w]/g, '_');
+    return /^\d+$/.test(s) ? s + 'a' : s;
+  }
+
+  describe("#getIn", function() {
+    it("gets a property by path", function () {
+      check(100, [TestUtils.ComplexObjectSpecifier()], function(ob) {
+        var immutable = Immutable(ob);
+
+        var path = [], depth = JSC.integer(1, 5)();
+        for (var j = 0; j < depth; j++) {
+          path.push(getPathComponent());
+        }
+
+        TestUtils.assertJsonEqual(
+          Immutable.getIn(immutable, path),
+          _.get(immutable, path)
+        );
+      });
+    });
+
+    it("returns the default value if the resolved value is undefined", function () {
+      check(100, [TestUtils.ComplexObjectSpecifier()], function(ob) {
+        var immutable = Immutable({ test: 'test'});
+
+        TestUtils.assertJsonEqual(
+          Immutable.getIn(immutable, ['notFound'], 'default'),
+          'default'
+        );
+      });
+    });
+
+    it("static method continues to work after overriding the instance method", function() {
+      var I = Immutable.static;
+
+      var immutable;
+
+      immutable = I({getIn: 'string'});
+      TestUtils.assertJsonEqual(immutable, {getIn: 'string'});
+      var value = I.getIn(immutable, ['getIn']);
+      TestUtils.assertJsonEqual(value, 'string');
+    });
+
+    it("supports non-static syntax", function() {
+      var obj = Immutable({ test: 'test' });
+      var value = obj.getIn(['test']);
+      TestUtils.assertJsonEqual(value, 'test');
+    });
+  });
+};