Background
I cannot seem to lose the reference to the original array I'm trying to clone. To illustrate my problem concretely, suppose I have the following.
JSBin: http://jsbin.com/fehoq/168/edit
student.scores: Array[3]
0: 12
1: 97
2: 81
My dropLowestScores
method then intends to find the two lowest values in the scores
array, copies them and put them in property lowest
.
student.lowest: Array[2]
0: 12
1: 81
Unfortunately, while I get the correct values in lowest
, rather than copying them from scores
, they are spliced. Not only that, but all values from my original array are depleted.
student.scores: Array[0]
This might make sense, given that I'm calling knockout's splice
method, but I'm calling it on a copy of the scores
array where I first called splice(0)
! I'm not sure if it matters, but the observable array I am splicing consists of observable numbers.
See the script below for details, or the JSBin above for the full thing.
Note that student
is just the model I'm working with.
JS
this.dropLowestScores = function() {
// find lowest scores for each student
ko.utils.arrayForEach(_this.students(), function(student){
//sporting function for observable values in array
var comparator = function(a,b){
if(a()<b()){
return -1;
} else if(a() > b()){
return 1;
} else {
return 0;
}
};
// tmp is a sorted clone of scores
var tmp = student.scores().sort(comparator).splice(0);
// set lowest to last two values in tmp array
student.lowest = tmp.splice((tmp.length-2),tmp.length);
// see what I'm getting
console.log(student.fullName());
console.log('student lowest: ' + student.lowest.length);
console.log('student scores: ' + student.scores().length);
});
};
Update
As edhedges pointed out, slice
is the correct method. The comparator
was also sorting opposite of how I intended.
A further point is that I cannot sort until tmp
is created, else it updates the view, which I do not desire.
The final version should look like the following.
this.dropLowestScores = function() {
ko.utils.arrayForEach(_this.students(), function(student){
var comparator = function(a,b){
if(a()<b()){
return 1;
} else if(a() > b()){
return -1;
} else {
return 0;
}
};
var tmp = student.scores().sort(comparator).slice(0);
student.lowest = tmp.splice((tmp.length-2),tmp.length-1);
});
};