Skip to content

Commit

Permalink
Merge pull request #1448 from ismell/duck
Browse files Browse the repository at this point in the history
Update the array utilities to use the native methods
  • Loading branch information
mbest committed Apr 15, 2017
2 parents 61c039f + 227e417 commit 668636e
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 10 deletions.
26 changes: 26 additions & 0 deletions spec/observableArrayChangeTrackingBehaviors.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,32 @@ describe('Observable Array change tracking', function() {
});
});

it('Converts a non array to an array', function() {
captureCompareArraysCalls(function(callLog) {
var myArray = ko.observable('hello').extend({'trackArrayChanges':true}),
changelist1;

myArray.subscribe(function(changes) { changelist1 = changes; }, null, 'arrayChange');
myArray(1);

// See that, not only did it invoke compareArrays only once, but the
// return values from getChanges are the same array instances
expect(callLog.length).toBe(1);
expect(changelist1).toEqual([
{ status: 'deleted', value: 'hello', index: 0 },
{ status: 'added', value: 1, index: 0 }
]);

// Objects get converted to Array
myArray({a: 1});
expect(callLog.length).toBe(2);
expect(changelist1).toEqual([
{ status: 'deleted', value: 1, index: 0 },
{ status: 'added', value: {a: 1}, index: 0 }
]);
});
});

it('Skips the diff algorithm when the array mutation is a known operation', function() {
captureCompareArraysCalls(function(callLog) {
var myArray = ko.observableArray(['Alpha', 'Beta', 'Gamma']),
Expand Down
6 changes: 3 additions & 3 deletions spec/utilsBehaviors.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ describe('arrayForEach', function () {
ko.utils.arrayForEach(["a", "b", "c"], callback);

expect(callback.calls.length).toBe(3);
expect(callback.calls[0].args).toEqual(["a", 0]);
expect(callback.calls[1].args).toEqual(["b", 1]);
expect(callback.calls[2].args).toEqual(["c", 2]);
expect(callback.calls[0].args).toEqual(["a", 0, ["a", "b", "c"]]);
expect(callback.calls[1].args).toEqual(["b", 1, ["a", "b", "c"]]);
expect(callback.calls[2].args).toEqual(["c", 2, ["a", "b", "c"]]);
});

it('Should do nothing with empty arrays', function () {
Expand Down
28 changes: 21 additions & 7 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,20 +102,27 @@ ko.utils = (function () {
fieldsIncludedWithJsonPost: ['authenticity_token', /^__RequestVerificationToken(_.*)?$/],

arrayForEach: function (array, action) {
if (array && typeof array.forEach == 'function') {
return array.forEach(action);
}
for (var i = 0, j = array.length; i < j; i++)
action(array[i], i);
action(array[i], i, array);
},

arrayIndexOf: function (array, item) {
if (typeof Array.prototype.indexOf == "function")
return Array.prototype.indexOf.call(array, item);
if (array && typeof array.indexOf == 'function') {
return array.indexOf(item);
}
for (var i = 0, j = array.length; i < j; i++)
if (array[i] === item)
return i;
return -1;
},

arrayFirst: function (array, predicate, predicateOwner) {
if (array && typeof array.find == 'function') {
return array.find(predicate, predicateOwner);
}
for (var i = 0, j = array.length; i < j; i++)
if (predicate.call(predicateOwner, array[i], i))
return array[i];
Expand All @@ -135,14 +142,18 @@ ko.utils = (function () {
arrayGetDistinctValues: function (array) {
array = array || [];
var result = [];
for (var i = 0, j = array.length; i < j; i++) {
if (ko.utils.arrayIndexOf(result, array[i]) < 0)
result.push(array[i]);
}
ko.utils.arrayForEach(array, function(item) {
if (ko.utils.arrayIndexOf(result, item) < 0)
result.push(item);
});

return result;
},

arrayMap: function (array, mapping) {
if (array && typeof array.map == 'function') {
return array.map(mapping);
}
array = array || [];
var result = [];
for (var i = 0, j = array.length; i < j; i++)
Expand All @@ -151,6 +162,9 @@ ko.utils = (function () {
},

arrayFilter: function (array, predicate) {
if (array && typeof array.filter == 'function') {
return array.filter(predicate);
}
array = array || [];
var result = [];
for (var i = 0, j = array.length; i < j; i++)
Expand Down

0 comments on commit 668636e

Please sign in to comment.