fnwiyaBlog

EmacsとかLispとか可視化とか

underscore.jsソースコードリーディング(Collections)

underscore.jsのソースコードリーディングを始めたのでその記録です。

Collectionsのメソッドは以下

  • each
  • map
  • reduce
  • reduceRight
  • find
  • filter
  • where
  • findWhere
  • reject
  • every
  • some
  • contains
  • invoke
  • pluck
  • max
  • min
  • sortBy
  • groupBy
  • indexBy
  • countBy
  • shuffle
  • sample
  • toArray
  • size
  • partition

学習メモ

  _.size = function(obj) {
    if (obj == null) return 0;
    return isArrayLike(obj) ? obj.length : _.keys(obj).length;
  };

の3行目のように? a : bの3項演算子で引数を判定しつつ結果を返すパターンが多い

知らなかったメソッドは(サンプル&ソースコードで羅列)

  _.pluck = function(obj, key) {
    return _.map(obj, _.property(key));
  };

var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}];
_.pluck(stooges, 'name');
=> ["moe", "larry", "curly"]


  var createReduce = function(dir) {
    // Optimized iterator function as using arguments.length
    // in the main function will deoptimize the, see #1991.
    var reducer = function(obj, iteratee, memo, initial) {
      var keys = !isArrayLike(obj) && _.keys(obj),
          length = (keys || obj).length,
          index = dir > 0 ? 0 : length - 1;
      if (!initial) {
        memo = obj[keys ? keys[index] : index];
        index += dir;
      }
      for (; index >= 0 && index < length; index += dir) {
        var currentKey = keys ? keys[index] : index;
        memo = iteratee(memo, obj[currentKey], currentKey, obj);
      }
      return memo;
    };

    return function(obj, iteratee, memo, context) {
      var initial = arguments.length >= 3;
      return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);
    };
  };

  // The right-associative version of reduce, also known as `foldr`.
  _.reduceRight = _.foldr = createReduce(-1);


var list = [[0, 1], [2, 3], [4, 5]];
var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
=> [4, 5, 2, 3, 0, 1]


  _.where = function(obj, attrs) {
    return _.filter(obj, _.matcher(attrs));
  };

_.where(listOfPlays, {author: "Shakespeare", year: 1611});
=> [{title: "Cymbeline", author: "Shakespeare", year: 1611},
    {title: "The Tempest", author: "Shakespeare", year: 1611}]


  _.invoke = restArgs(function(obj, method, args) {
    var isFunc = _.isFunction(method);
    return _.map(obj, function(value) {
      var func = isFunc ? method : value[method];
      return func == null ? func : func.apply(value, args);
    });
  });

_.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
=> [[1, 5, 7], [1, 2, 3]]