Reputation: 133
Let's say I have two arrays:
a=[168, 76, 62, 86]
b=[168, 80, 65, 90]
My input
[166.5, 75.5, 62, 86]
Now I want to get array "a" as my "result" because it is more similar to "a" than it is to "b".
How can I do that?
Upvotes: 1
Views: 1130
Reputation: 596
Let's say that you've got two number arrays
x = [x1, x2, ..., xn]
y = [y1, y2, ..., yn]
The difference (i.e inverse similarity) between them is calculated by passing them through some error function E let's say
E = Σ (xi - yi)2
it's the same as calculating:
(x1 - y2)2 + ... + (xn - yn)2
= Σx2 + Σy2 - Σ(2xiyi)
= Σxi2 + Σyi2 - 2ΣxiΣyi
which means we can now use just the built-in Javascript methods .map()
and .reduce()
.
const toSquare(ar) = ar.map( v => v*v )
const sum(ar) = ar.reduce( (acc, v) => acc + v )
function error(ar1, ar2) {
return sum(toSquare(ar1)) + sum(toSquare(ar2)) + 2*sum(ar1)*sum(ar2)
}
Much simpler:
you can also use underscore's or lodash's .zip
function:
function error(ar1, ar2) {
return _.zip([ar1, ar2]).map( pair => Math.pow(p[0]-p[1], 2) ).reduce( (acc, v) => acc + v )
}
Upvotes: 2
Reputation: 386654
You could collect the absolute deltas and choose the one with the smaller error.
var array1 = [168, 76, 62, 86],
array2 = [168, 80, 65, 90],
input = [166.5, 75.5, 62, 86],
error = [array1, array2].map(function (a) {
return input.reduce(function (r, b, i) {
return r + Math.abs(a[i] -b);
}, 0);
});
console.log(error); // [2, 13] take the first one with smaller error.
Upvotes: 5
Reputation: 2489
You will have to create a manual function to do that. There is no built in way to do so.
function closest( inputArray, controlArrays) {
var margins;
for(var i=0, iMax=controlArrays.length; i < iMax; i++ ){
margins[i] = 0;
for(var j=0, jMax=inputArray.length; j < jMax; j++) {
//get the difference between the numbers and add it for the margins for that control array
margins[i] += Math.abs(inputArray[j]-controlArrays[j][i]);
}
}
//find smallest margin
var index = 0;
var value = margins[0];
for (var m = 1, mMax = temp.length; m < mMax; m++) {
if (temp[m] < value) {
value = temp[m];
index = m;
}
}
//return the smalles margin;
return controlArrays[index];
}
Upvotes: 1