Reputation: 2155
I'm attempting to check the existence of a value in array A in a second array, B. Each value is an observable number. Each observable number is contained in an observable array. The comparison always returns -1, which is known to be incorrect (insofar as values in A and B overlap). Therefore, there's something wrong with my logic or syntax, but I have not been able to figure out where.
JSBin (full project): http://jsbin.com/fehoq/190/edit
//set up my two arrays that will be compared
this.scores = ko.observableArray();
//lowest is given values from another method that splices from scores
this.lowest = ko.observableArray();
//computes and returns mean of array less values in lowest
this.mean = (function(scores,i) {
var m = 0;
var count = 0;
ko.utils.arrayForEach(_this.scores(), function(score) {
if (!isNaN(parseFloat(score()))) {
//check values
console.log(score());
// always returns -1
console.log(_this.lowest.indexOf(score()));
//this returns an error, 'not a function'
console.log(_this.lowest()[i]());
//this returns undefined
console.log(_this.lowest()[i]);
//only do math if score() isn't in lowest
// again, always returns -1, so not a good check
if (_this.lowest.indexOf(score())<0) {
m += parseFloat(score());
count += 1;
}
}
});
// rest of the math
if (count) {
m = m / count;
return m.toFixed(2);
} else {
return 'N/A';
}
});
@Major Byte noted that mean() is calculated before anything gets pushed to lowest
, hence why I get undefined
. If this is true, then what might be the best way to ensure that mean() will update based on changes to lowest
?
Upvotes: 1
Views: 252
Reputation: 4101
You really just could use a computed for the mean
this.mean = ko.computed(
function() {
var sum = 0;
var count = 0;
var n = 0;
for(n;n < _this.scores().length;n++)
{
var score = _this.scores()[n];
if (_this.lowest.indexOf(score)<0) {
sum += parseFloat(score());
count++;
}
}
if (count > 0) {
sum = sum / count;
return sum.toFixed(2);
} else {
return 'N/A';
}
});
this will trigger when you add to lower(), scores() and change scores().
Update:
Forgot to mention that I change something crucial as well. From you original code:
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 = ko.observableArray(tmp.splice((tmp.length-2),tmp.length-1));
});
};
apart from moving the comparator
outside of dropLowestScores
function, I changed the line:
student.lowest = ko.observableArray(tmp.splice((tmp.length-2),tmp.length-1));
to
student.lowest(tmp.splice((tmp.length-2),tmp.length-1));
student.lowest
is an observable array, no need to define it as an observableArray again, in fact that actually breaks the computed mean
. (The correction for Drop Lowest Scores as per my previous comment is left out here).
Upvotes: 3