I have 3 numbers in an array that I want to order so that the item closest to 2 is in the middle, the lowest from two on the left and the highest from two on the right.
example 1 - [2.3, 5.2, 1.2];
should change to [1.2, 2.3, 5.2];
example 2 - [1.1, 2.3, 0.3];
which should change to [0.3, 2.3, 1.1];
example 3 - [1.3, 0.3, 2];
which should change to [0.3, 2, 1.3];
example 4 - [2.2, 2.3, 2.1];
which should change to [2.2, 2.1, 2.3];
Currently I have the following but this is not ordering correctly. This puts the item closest to 2 at the front.
arr.sort(function(a, b){
return Math.abs(1 - (a - 2)) - Math.abs(1 - (b - 2));
});
Can anyone see how this needs to be changed?
You need a three step approach, first sort to get the closest to the given value, shift that value and sort the rest ascending. Then plice the temporary value to index 1
.
function sort(array) {
var temp = array.sort((a, b) => Math.abs(x - a) - Math.abs(x - b)).shift();
array.sort((a, b) => a - b).splice(1, 0, temp);
return array;
}
var x = 2;
console.log(sort([0, 1, 2]));
console.log(sort([1, 2, 3]));
console.log(sort([2, 3, 4]));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Another solution would be to collect the values with bigger delta in a new array and sort it. Later put the reduced value back to index 1
.
Advantage: No superfluous sort, while only one iteration is needed.
function sort(array) {
var temp = [],
value = array.reduce((a, b) =>
Math.abs(x - a) < Math.abs(x - b) ? (temp.push(b), a) : (temp.push(a), b)
);
temp.sort((a, b) => a - b).splice(1, 0, value);
return temp;
}
var x = 2;
console.log(sort([0, 1, 2]));
console.log(sort([1, 2, 3]));
console.log(sort([2, 3, 4]));
.as-console-wrapper { max-height: 100% !important; top: 0; }
To easy, sort after distance to 2, then put the first into the second position:
arr.sort((a,b)=>Math.abs(a-2)-Math.abs(b-2));
arr=[arr[1],arr[0],arr[2]];
http://jsbin.com/kifitosopo/edit?console
You could do it using one reducer with straight forward rules.
const diff = value => Math.abs(value - 2)
const sort = arr => arr.reduce(([min, closest, max], value) => {
if(closest !== closest || diff(value) < diff(closest)) [closest, value] = [value, closest]
if(min !== min || value < min ) min = value
if(max !== max || value > max ) max = value
return [min, closest, max]
}, new Array(3).fill(NaN))
const tests = [
[2.3, 5.2, 1.2],
[1.1, 2.3, 0.3],
[1.3, 0.3, 2],
[2.2, 2.3, 2.1]
]
tests.forEach(test => console.log(`[${test.join(', ')}] --> [${sort(test).join(', ')}]`))