Skip to content
Jeeeyul Lee edited this page Feb 5, 2015 · 38 revisions

valueForKeyPath(obj, keyPath, [fallbackValue])

Returns a value for given key path("." separated property names) You can call this method with "setValueForKeyPath" also.

  • obj : An object to get value of property.
  • keyPath : "." separated property names or an array containing property names.
  • fallbackValue : fallback value which will be retuned when there is no matching value or null or undefined for given key path.
var obj = {
  foo : {
    bar : "test"
  }
};

_(obj).valueForKeyPath("foo.bar"); // --> "test"
_(obj).valueForKeyPath(["foo", "bar"]); // --> "test"
_(obj).valueForKeyPath("foo.zar.notExistingProperty", "fallback"); // --> "fallback"

Getter method

What if there is a getter for given keypath, underscore-keypath tries to use it.

var bar = {
  _name : "Hello",
  _valid : true
};

bar.getName = function(){
  return this._name;
};

bar.isValid = function(){
  return this._valid;
}

_(bar).valueForKeyPath("name"); // --> "Hello"
_(bar).valueForKeyPath("valid"); // --> true

var foo = {
  "bar" : bar
};

_(foo).valueForKeyPath("bar.name") // --> Hello
//                      ^^^ 
//                        will be passed as "this" to getter

Function property

Each segment in key path can be used to call a function of current context:

var foo = {
  bar : function(){
    return {
      zar : function(){
        return "cool!";
      }    
    }
  }
};

_(foo).valueForKeyPath("bar.zar"); // --> foo.bar().zar() : "cool!" 

Access Array

You can access elements in array with number:

var obj = {
  data : ["foo", "bar"]
};

_(obj).valueForKeyPath("data.0"); // --> "foo"

What if current context is an instance of Array, You can use element selector(starts with "@") on your key path.

  • @first : first element
  • @last : last element
  • @max : (READONLY) max value element
  • @min : (READONLY) min value element
  • @size : (READONLY) size of array
var elements = [
  {
     data : [1, 2, 3, 4, 5]
  },
  {
     data : [10, 20, 30, 40, 50]
  }
]

_(elements).valueForKeyPath("@first.@size"); // --> 5
_(elements).valueForKeyPath("@last.@max"); // --> 50

setValueForKeyPath(obj, keypath, newValue)

Sets a value for property of given key path to given object. What if there is no matching context in given object, it will be ignored.

pluckByKeyPath(list, keyPath)

Plucks and returns an array with given key path.

  • list : a collection
  • keyPath : keyPath to pluck
var list = [
  {
    foo : {
      bar : "first"
    }
  },
  {
    foo : {
      bar : "second"
    }
  }
];

_(list).pluckByKeyPath("foo.bar"); // --> ["first", "second"]

whereByKeyPath(list, query)

Returns a array which contains elements which are matched with given query(key-value json) object.

  • list : collection to query.
  • query : filter that composed with key and expected value.
var list = [
  {
    name : "foo",
    age : 1,
    company : {
      name : "nodejs"
    }
  },
  {
    name : "bar",
    age : 2,
    company : {
      name : "nodejs"
    }
  },
  {
    name : "zar",
    age : 3,
    company : {
      name : "nodejs"
    }
  }
];

_(list).whereByKeyPath({"company.name" : "nodejs"});
// --> [{name:"foo",...}, {name:"bar", ...}]

findWhereByKeyPath(list, query)

Just same as whereByKeypath but it returns only first matching element not an array.

  • list : a collection to lookup
  • query : key-value JSON Object to find.
var list = [
  {
    name : "foo",
    age : 1,
    company : {
      name : "nodejs"
    }
  },
  {
    name : "bar",
    age : 2,
    company : {
      name : "nodejs"
    }
  },
  {
    name : "zar",
    age : 3,
    company : {
      name : "nodejs"
    }
  }
];

_(list).whereByKeyPath({"company.name" : "nodejs"});
// --> {name:"foo",...}

countByKeyPath(array, keyPath)

  • array
  • keypath
var list = [
  {
    name : "foo",
    info : {
      favoriteColor : "red"
    }
  },
  {
    name : "bar",
    info : {
      favoriteColor : "green"
    }
  },
  {
    name : "zar",
    info : {
      favoriteColor : "red"
    }
  }
];

_(list).countByKeyPath("info.favoriteColor");
// --> {"red" : 2, "green" : 1}

sortByKeyPath(array, keyPath)

  • array
  • keyPath
var list = [
  {
    name : "foo",
    info : {
      favoriteColor : "red",
      age : 5
    }
  },
  {
    name : "bar",
    info : {
      favoriteColor : "green",
      age : 1
    }
  },
  {
    name : "zar",
    info : {
      favoriteColor : "red",
      age : 3
    }
  }
];

_(list).sortByKeyPath("info.age");
// --> [{name:"bar", ...}, {name:"zar", ...}, {name:"foo", ...}]

groupByKeyPath(array, keypath)

Groups elements in an array with given key path. *array : array to group *keypath : key path to use as group key

_(list).groupByKeyPath("info.favoriteColor");
/* 
 * {
 *   "red" : [{name : "foo", ...}, {name : "zar", ...}],
 *   "green": [{name : "bar", ...}]
 * }
 */

indexByKeyPath(array, keypath)

Same as groupByKeyPath, but it assumes that each group key value is unique over the elements. What if multiple elements have same value for given index key path, they are ignored but first one.

_(list).groupByKeyPath("info.favoriteColor");
/* 
 * {
 *   "red" : {name : "foo", ...},
 *   "green": {name : "bar", ...}
 * }
 */

hasKeyPath(array, keypath)

var fixture = {
  foo : {
    bar : "zar"
  }
};
fixture.getName = function(){
  return "fixture";
};

_(fixture).hasKeyPath("foo.bar"); // --> true
_(fixture).hasKeyPath("name"); // --> true