Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Livesense tech night immutable-js at a glance

immutable-jsのListの実装について

  • Soyez le premier à commenter

Livesense tech night immutable-js at a glance

  1. 1. Immutable @ JavaScript
  2. 2. var  me  =  {      name:      "Yuta  Shimakawa",      tw:          "@banana_umai",      qiita:    "bananaumai",      github:  "bananaumai"   };
  3. 3. ではございません
  4. 4. at a glance...
  5. 5. 不変データ Seq List Map OrderedMap Set OrderedSet Record
  6. 6. var  list1  =  Immutable.List.of(1,  2);   var  list2  =  list1.push(3,  4,  5);   var  list3  =  list2.unshift(0);   var  list4  =  list1.concat(list2,  list3);   assert(list1.size  ===  2);   assert(list2.size  ===  5);   assert(list3.size  ===  6);   assert(list4.size  ===  13);   assert(list4.get(0)  ===  1);   https://github.com/facebook/immutable-js/
  7. 7. JSオブジェクトとの 相互変換
  8. 8. var  map1  =  Immutable.Map({a:1,  b:2,  c:3,  d:4});   var  map2  =  Immutable.Map({c:10,  a:20,  t:30});   var  obj  =  {d:100,  o:200,  g:300};   var  map3  =  map1.merge(map2,  obj);   //  Map  {  a:  20,  b:  2,  c:  10,  d:  100,  t:  30,  o:  200,  g:  300  } https://github.com/facebook/immutable-js/ var  deep  = Immutable.Map(   {  a:  1,  b:  2,  c:  Immutable.List.of(3,  4,  5)  });   deep.toObject()  //  {  a:  1,  b:  2,  c:  List  [  3,  4,  5  ]  }   deep.toArray()  //  [  1,  2,  List  [  3,  4,  5  ]  ]   deep.toJS()  //  {  a:  1,  b:  2,  c:  [  3,  4,  5  ]  }   JSON.stringify(deep)  //  '{"a":1,"b":2,"c":[3,4,5]}'
  9. 9. 入れ子データ
  10. 10. var  nested  =  Immutable.fromJS({a:{b:{c:[3,4,5]}}});   //  Map  {  a:  Map  {  b:  Map  {  c:  List  [  3,  4,  5  ]  }  }  }   var  nested2  =  nested.mergeDeep({a:{b:{d:6}}});   //  Map  {  a:  Map  {  b:  Map  {  c:  List  [  3,  4,  5  ],  d:  6  }  }  }   var  nested3  =   nested2.updateIn(['a',  'b',  'd'],  value  =>  value  +  1);   //  Map  {  a:  Map  {  b:  Map  {  c:  List  [  3,  4,  5  ],  d:  7  }  }  }   var  nested4     =  nested3.updateIn(['a',  'b',  'c'],  list  =>  list.push(6));   //  Map  {  a:  Map  {  b:  Map  {  c:  List  [  3,  4,  5,  6  ],  d:  7  }  }  } https://github.com/facebook/immutable-js/
  11. 11. 遅延評価(Seq)
  12. 12. var  oddSquares  =  Immutable.Seq.of(1,2,3,4,5,6,7,8)                                      .filter(x  =>  x  %  2)                                      .map(x  =>  x  *  x);  //  not  computed  here!       oddSquares.get(1);  //  9 https://github.com/facebook/immutable-js/
  13. 13. 同等性
  14. 14. var  map1  =  Immutable.Map({a:1,  b:1,  c:1});   var  map2  =  Immutable.Map({a:1,  b:1,  c:1});   assert(map1  !==  map2);   assert(Immutable.is(map1,  map2)  ===  true); https://github.com/facebook/immutable-js/
  15. 15. JSで不変データ
  16. 16. Immutableなリストを 素朴に実装してみた
  17. 17. cloneによる実装
  18. 18. var  _  =  require('lodash');       function  iPush(arr,  val)  {      var  arr2  =  _.clone(arr);      arr2.push(val);      return  arr2;   }       var  arr  =  [];   for  (var  i  =  0;  i  <  100000;  i++)  {      arr  =  iPush(arr,  i);   } https://gist.github.com/bananaumai/cc2f4d90662aa823ce9e
  19. 19. …は cloneのコストが膨大
  20. 20. Linked Listを実装
  21. 21. var  LinkedList  =  {};   LinkedList.prototype  =  {      head:  function()  {          return  this._head;      },          tail:  function()  {          return  this._tail;      },          push:  function(val)  {          return  new  NonEmptyList(val,  this);      },          forEach:  function(fnc)  {          fnc(this._head);          if  (this._tail  instanceof  NonEmptyList)  {              this._tail.forEach(fnc);          }      }   };   var  EmptyList  =  function()  {      this._head  =  null;      this._tail  =  null;   };   EmptyList.prototype  =  Object.create(LinkedList.prototype);   EmptyList.prototype.constructor  =  EmptyList; https://gist.github.com/bananaumai/164b24b264e0f917007c var  NonEmptyList  =  function(head,  tail)  {      this._head  =  head;      this._tail  =  tail;   };   NonEmptyList.prototype  =   Object.create(LinkedList.prototype);   NonEmptyList.prototype.constructor  =  NonEmptyList;     LinkedList.of  =  function()  {      var  _create  =  function(vals,  list)  {          if  (vals.length  ===  0)  return  list;          var  head  =  vals.shift();          return  _create(vals,  new  NonEmptyList(head,  list))      };          return  _create(          Array.prototype.slice.call(arguments).reverse(),          new  EmptyList()      );   };
  22. 22. var  list  =  LinkedList.of();   for  (var  i  =  0;  i  <  100000;  i++)  {      list  =  list.push(i);   }   https://gist.github.com/bananaumai/164b24b264e0f917007c
  23. 23. …は (&pushはそれなりに速いけど・・・) 末尾再帰最適化 されないので難しい (&Object.ArrayのAPIの実現しようとすると・・・)
  24. 24. immutable-jsのアプローチ
  25. 25. Trie http://ja.wikipedia.org/wiki/%E3%83%88%E3%83%A9%E3%82%A4%E6%9C%A8
  26. 26. (def  list  [0  1  2  3  4  5])
  27. 27. ClojureやScalaが採用 しているアプローチ
  28. 28. Immutable.Listの実装
  29. 29. 文字列のキーの代わりに 添字の数値をbitに変換、 パーティショニング
  30. 30. var  list  =  Immutable.List.of(1,…,1000);   list.get(887); http://hypirion.com/musings/understanding-persistent-vector-pt-2#f1n
  31. 31. 実際は5bitずつ分割するので ↓ O(Log32N)
  32. 32. 実際は32通り http://hypirion.com/musings/understanding-persistent-vector-pt-1
  33. 33. var  list1  =  Immutable.List.of(1,2,3,4,5,6,7,8);   var  list2  =  list1.set(5,  "beef"); list1 list2 http://hypirion.com/musings/understanding-persistent-vector-pt-1
  34. 34. 要素のpush var  list1  =  Immutable.List.of(…);   var  list2  =  list.push(…);
  35. 35. 最右のリーフノードに空きがある場合 http://hypirion.com/musings/understanding-persistent-vector-pt-1
  36. 36. 最右のリーフノードに空きがない場合 http://hypirion.com/musings/understanding-persistent-vector-pt-1
  37. 37. rootから伸びるすべてのリーフが埋まっている場合 http://hypirion.com/musings/understanding-persistent-vector-pt-1
  38. 38. 要素のpop var  list1  =  Immutable.List.of(…);   var  list2  =  list.pop();
  39. 39. 最右のリーフノードが2つ以上の要素を持つ場合 http://hypirion.com/musings/understanding-persistent-vector-pt-1
  40. 40. 最右のリーフノードが1つの要素を持つ場合 http://hypirion.com/musings/understanding-persistent-vector-pt-1
  41. 41. 削除後rootノードが1つの要素だけをもつ場合 http://hypirion.com/musings/understanding-persistent-vector-pt-1
  42. 42. 簡単なまとめ
  43. 43. Trieによるリストの表現 O(Log32N)のアクセス 最小限のコピー

×