scan.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojox.lang.functional.scan"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.lang.functional.scan"] = true;
  8. dojo.provide("dojox.lang.functional.scan");
  9. dojo.require("dojox.lang.functional.lambda");
  10. // This module adds high-level functions and related constructs:
  11. // - "scan" family of functions
  12. // Notes:
  13. // - missing high-level functions are provided with the compatible API:
  14. // scanl, scanl1, scanr, scanr1
  15. // Defined methods:
  16. // - take any valid lambda argument as the functional argument
  17. // - operate on dense arrays
  18. // - take a string as the array argument
  19. // - take an iterator objects as the array argument (only scanl, and scanl1)
  20. (function(){
  21. var d = dojo, df = dojox.lang.functional, empty = {};
  22. d.mixin(df, {
  23. // classic reduce-class functions
  24. scanl: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object*/ z, /*Object?*/ o){
  25. // summary: repeatedly applies a binary function to an array from left
  26. // to right using a seed value as a starting point; returns an array
  27. // of values produced by foldl() at that point.
  28. if(typeof a == "string"){ a = a.split(""); }
  29. o = o || d.global; f = df.lambda(f);
  30. var t, n, i;
  31. if(d.isArray(a)){
  32. // array
  33. t = new Array((n = a.length) + 1);
  34. t[0] = z;
  35. for(i = 0; i < n; z = f.call(o, z, a[i], i, a), t[++i] = z);
  36. }else if(typeof a.hasNext == "function" && typeof a.next == "function"){
  37. // iterator
  38. t = [z];
  39. for(i = 0; a.hasNext(); t.push(z = f.call(o, z, a.next(), i++, a)));
  40. }else{
  41. // object/dictionary
  42. t = [z];
  43. for(i in a){
  44. if(!(i in empty)){
  45. t.push(z = f.call(o, z, a[i], i, a));
  46. }
  47. }
  48. }
  49. return t; // Array
  50. },
  51. scanl1: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
  52. // summary: repeatedly applies a binary function to an array from left
  53. // to right; returns an array of values produced by foldl1() at that
  54. // point.
  55. if(typeof a == "string"){ a = a.split(""); }
  56. o = o || d.global; f = df.lambda(f);
  57. var t, n, z, first = true;
  58. if(d.isArray(a)){
  59. // array
  60. t = new Array(n = a.length);
  61. t[0] = z = a[0];
  62. for(var i = 1; i < n; t[i] = z = f.call(o, z, a[i], i, a), ++i);
  63. }else if(typeof a.hasNext == "function" && typeof a.next == "function"){
  64. // iterator
  65. if(a.hasNext()){
  66. t = [z = a.next()];
  67. for(var i = 1; a.hasNext(); t.push(z = f.call(o, z, a.next(), i++, a)));
  68. }
  69. }else{
  70. // object/dictionary
  71. for(var i in a){
  72. if(!(i in empty)){
  73. if(first){
  74. t = [z = a[i]];
  75. first = false;
  76. }else{
  77. t.push(z = f.call(o, z, a[i], i, a));
  78. }
  79. }
  80. }
  81. }
  82. return t; // Array
  83. },
  84. scanr: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object*/ z, /*Object?*/ o){
  85. // summary: repeatedly applies a binary function to an array from right
  86. // to left using a seed value as a starting point; returns an array
  87. // of values produced by foldr() at that point.
  88. if(typeof a == "string"){ a = a.split(""); }
  89. o = o || d.global; f = df.lambda(f);
  90. var n = a.length, t = new Array(n + 1), i = n;
  91. t[n] = z;
  92. for(; i > 0; --i, z = f.call(o, z, a[i], i, a), t[i] = z);
  93. return t; // Array
  94. },
  95. scanr1: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
  96. // summary: repeatedly applies a binary function to an array from right
  97. // to left; returns an array of values produced by foldr1() at that
  98. // point.
  99. if(typeof a == "string"){ a = a.split(""); }
  100. o = o || d.global; f = df.lambda(f);
  101. var n = a.length, t = new Array(n), z = a[n - 1], i = n - 1;
  102. t[i] = z;
  103. for(; i > 0; --i, z = f.call(o, z, a[i], i, a), t[i] = z);
  104. return t; // Array
  105. }
  106. });
  107. })();
  108. }