lazy-array.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. ({define:typeof define!="undefined"?define:function(deps, factory){module.exports = factory.apply(this, deps.map(function(id){return require(id)}))}}).
  2. define(["./promise"], function(promise){
  3. try{
  4. var when = promise.when;
  5. }catch(e){
  6. console.log("couldn't load promise library", e.stack);
  7. when = function(value, callback){
  8. return callback(value);
  9. }
  10. }
  11. function LazyArray(hasSomeAndLength){
  12. return new SomeWrapper(hasSomeAndLength);
  13. };
  14. var exports = LazyArray;
  15. exports.LazyArray = LazyArray;
  16. exports.first = function(array){
  17. return exports.get(array, 0);
  18. };
  19. exports.last = function(array){
  20. return exports.get(array, array.length-1);
  21. };
  22. exports.get = function(array, index){
  23. var result, i = 0;
  24. return when(array.some(function(item){
  25. if(i == index){
  26. result = item;
  27. return true;
  28. }
  29. i++;
  30. }),
  31. function(){
  32. return result;
  33. });
  34. };
  35. var testProto = {};
  36. var testProto2 = {a:"b"};
  37. testProto.__proto__ = testProto2;
  38. var mutableProto = testProto.a == "b";
  39. function SomeWrapper(hasSomeAndLength){
  40. if(mutableProto){
  41. hasSomeAndLength.source = hasSomeAndLength;
  42. hasSomeAndLength.__proto__ = SomeWrapper.prototype;
  43. return hasSomeAndLength;
  44. }
  45. this.source = hasSomeAndLength;
  46. if(hasSomeAndLength.length){
  47. this.length = hasSomeAndLength.length;
  48. }
  49. this.totalCount = hasSomeAndLength.totalCount;
  50. }
  51. exports.LazyArray.prototype = SomeWrapper.prototype = [];
  52. SomeWrapper.prototype.some = function(callback){
  53. this.source.some(callback);
  54. }
  55. SomeWrapper.prototype.filter = function(fn, thisObj){
  56. var results = [];
  57. return when(this.source.some(function(item){
  58. if(fn.call(thisObj, item)){
  59. results.push(item);
  60. }
  61. }), function(){
  62. return results;
  63. });
  64. };
  65. SomeWrapper.prototype.every = function(fn, thisObj){
  66. return when(this.source.some(function(item){
  67. if(!fn.call(thisObj, item)){
  68. return true;
  69. }
  70. }), function(result){return !result;});
  71. };
  72. SomeWrapper.prototype.forEach= function(fn, thisObj){
  73. return this.source.some(function(item){
  74. fn.call(thisObj, item);
  75. });
  76. };
  77. SomeWrapper.prototype.concat = function(someOther){
  78. var source = this.source;
  79. return new SomeWrapper({
  80. length : source.length + someOther.length,
  81. some : function(fn,thisObj){
  82. return when(source.some(fn,thisObj), function(result){
  83. return result || someOther.some(fn,thisObj);
  84. });
  85. }
  86. });
  87. };
  88. SomeWrapper.prototype.map = function(mapFn, mapThisObj){
  89. var source = this.source;
  90. return new SomeWrapper({
  91. length : source.length,
  92. some : function(fn,thisObj){
  93. return source.some(function(item){
  94. return fn.call(thisObj, mapFn.call(mapThisObj, item));
  95. });
  96. }
  97. });
  98. };
  99. SomeWrapper.prototype.toRealArray= function(mapFn, mapThisObj){
  100. var array = [];
  101. return when(this.source.some(function(item){
  102. array.push(item);
  103. }), function(){
  104. return array;
  105. });
  106. };
  107. SomeWrapper.prototype.join = function(){
  108. var args = arguments;
  109. return when(this.toRealArray(), function(realArray){
  110. return Array.prototype.join.apply(realArray, args);
  111. });
  112. };
  113. SomeWrapper.prototype.sort = function(){
  114. var args = arguments;
  115. return when(this.toRealArray(), function(realArray){
  116. return Array.prototype.sort.apply(realArray, args);
  117. });
  118. };
  119. SomeWrapper.prototype.reverse = function(){
  120. var args = arguments;
  121. return when(this.toRealArray(), function(realArray){
  122. return Array.prototype.reverse.apply(realArray, args);
  123. });
  124. };
  125. SomeWrapper.prototype.get = SomeWrapper.prototype.item = function(index){
  126. var result, i = 0;
  127. return when(this.source.some(function(item){
  128. if(i == index){
  129. result = item;
  130. return true;
  131. }
  132. i++;
  133. }), function(){
  134. return result;
  135. });
  136. };
  137. SomeWrapper.prototype.toSource = function(){
  138. var serializedParts = [];
  139. return when(this.source.some(function(item){
  140. serializedParts.push(item && item.toSource());
  141. }), function(){
  142. return '[' + serializedParts.join(",") + ']';
  143. });
  144. };
  145. SomeWrapper.prototype.toJSON = function(){
  146. var loadedParts = [];
  147. return when(this.source.some(function(item){
  148. loadedParts.push(item);
  149. }), function(){
  150. return loadedParts;
  151. });
  152. };
  153. return exports;
  154. });