Skip to content
This repository was archived by the owner on Mar 13, 2018. It is now read-only.

Commit 3c8009e

Browse files
committed
Simplified ArrayReduction
1 parent 036fb3c commit 3c8009e

File tree

2 files changed

+47
-76
lines changed

2 files changed

+47
-76
lines changed

tests/test_array_reduction.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ suite('ArrayReduction Tests',function(){
1515
path: 'id',
1616
initial: [],
1717
reduce: function(value,cur,i){
18-
value.push([cur,i]);
18+
value.push([cur.id,i]);
1919
return value;
2020
}
2121
});

util/array_reduction.js

+46-75
Original file line numberDiff line numberDiff line change
@@ -13,98 +13,69 @@
1313
// limitations under the License.
1414

1515
function ArrayReduction(array, path, reduceFn, initial) {
16-
var values = [];
17-
var observers = [];
18-
var self = this;
19-
var hasInitial = arguments.length == 4;
20-
21-
function reduce() {
22-
self.value = hasInitial ?
23-
values.reduce(reduceFn, initial) : values.reduce(reduceFn);
24-
}
25-
26-
function newCallback(index) {
27-
return function(value) {
28-
values[index] = value;
29-
reduce();
30-
}
31-
}
32-
33-
function handleSplice(splice) {
34-
var valueArgs = [splice.index, splice.removed.length];
35-
var observerArgs = [splice.index, splice.removed.length];
16+
this.array = array;
17+
this.path = path ? path.trim() : undefined;
18+
this.reduceFn = reduceFn;
19+
this.initial = initial;
20+
this.arrayObserver = new ArrayObserver(array, this.handleSplices, this);
21+
this.observers = this.path ? [] : undefined;
22+
23+
this.handleSplices([{
24+
index: 0,
25+
removed: [],
26+
addedCount: array.length
27+
}]);
28+
}
3629

37-
var removeIndex = splice.index;
38-
while (removeIndex < splice.index + splice.removed.length) {
39-
observers[removeIndex].close();
40-
observers[removeIndex] = undefined;
41-
removeIndex++;
42-
}
30+
ArrayReduction.prototype = {
31+
updateObservers: function(splices) {
32+
for (var i = 0; i < splices.length; i++) {
33+
var splice = splices[i];
34+
var added = [];
35+
for (var j = 0; j < splice.addedCount; j++) {
36+
added.push(new PathObserver(this.array[splice.index + j], this.path,
37+
this.reduce, this));
38+
}
4339

44-
var addIndex = splice.index;
45-
while (addIndex < splice.index + splice.addedCount) {
46-
var itemPath = String(addIndex);
47-
if (path)
48-
itemPath += '.' + path;
40+
var spliceArgs = [splice.index, splice.removed.length].concat(added);
41+
var removed = Array.prototype.splice.apply(this.observers, spliceArgs);
4942

50-
valueArgs.push(PathObserver.getValueAtPath(array, itemPath));
51-
observerArgs.push(new PathObserver(array, itemPath, newCallback(addIndex)));
52-
addIndex++;
43+
for (var j = 0; j < removed.length; j++) {
44+
removed[j].close();
45+
}
5346
}
47+
},
5448

55-
Array.prototype.splice.apply(values, valueArgs);
56-
Array.prototype.splice.apply(observers, observerArgs);
57-
58-
// Correct the index/path being watched by the observers that watched indices
59-
// after the splice.
60-
var curIndex = splice.index + splice.addedCount;
61-
while(curIndex < values.length) {
62-
var expectedItemPath = (path ? (curIndex + '.' + path) : String(curIndex));
63-
64-
observers[curIndex].close();
65-
observers[curIndex] = new PathObserver(array, expectedItemPath, newCallback(curIndex));
66-
curIndex++;
67-
}
68-
}
49+
handleSplices: function(splices) {
50+
if (this.observers)
51+
this.updateObservers(splices);
6952

70-
var arrayObserver = new ArrayObserver(array, function(splices) {
71-
splices.forEach(handleSplice);
72-
reduce();
73-
});
53+
this.reduce();
54+
},
7455

75-
handleSplice({
76-
index: 0,
77-
removed: [],
78-
addedCount: array.length
79-
});
56+
reduce: function() {
57+
this.value = this.array.reduce(this.reduceFn, this.initial);
58+
},
8059

81-
this.close = function() {
82-
observers.forEach(function(observer) {
60+
close: function() {
61+
this.observers.forEach(function(observer) {
8362
observer.close();
8463
});
85-
arrayObserver.close();
86-
};
87-
88-
this.unobserved = function() {
89-
self.close();
90-
};
64+
this.arrayObserver.close();
65+
},
9166

92-
this.deliver = function() {
93-
arrayObserver.deliver();
94-
observers.forEach(function(observer) {
67+
deliver: function() {
68+
this.arrayObserver.deliver();
69+
this.observers.forEach(function(observer) {
9570
observer.deliver();
9671
});
9772
}
98-
99-
reduce();
10073
}
10174

10275
ArrayReduction.defineProperty = function(object, name, descriptor) {
103-
var observer;
104-
if (descriptor.hasOwnProperty('initial'))
105-
observer = new ArrayReduction(descriptor.array, descriptor.path, descriptor.reduce, descriptor.initial);
106-
else
107-
observer = new ArrayReduction(descriptor.array, descriptor.path, descriptor.reduce);
76+
var observer = new ArrayReduction(descriptor.array, descriptor.path,
77+
descriptor.reduce,
78+
descriptor.initial);
10879

10980
Object.defineProperty(object, name, {
11081
get: function() {

0 commit comments

Comments
 (0)