The return index of the closest values ​​in the array

I have it:

var scores=[0.7, 1.05, 0.81, 0.96, 3.2, 1.23]; 

What is a more readable way to return the indices of the nearest values ​​of another variable?

For instance:

Variable = 1 Must return { low: 3, high: 1 }

+6
source share
7 answers

Almost as simple, but faster (O (n)) than sorting:

 const nearest = (arr, n) => arr.reduce((r, x) => ({ lo: ((x < n) && (x > r.lo) ? x : r.lo), hi: ((x > n) && (x < r.hi) ? x : r.hi) }), { lo: -Infinity, hi: Infinity }) const mapIndexOf = (obj, lookup) => Object.keys(obj).reduce( (a, v) => ({ ...a, [v]: lookup.indexOf(obj[v]) }), {} ) const scores = [0.7, 1.05, 0.81, 0.96, 3.2, 1.23] console.log(mapIndexOf(nearest(scores, 1), scores)) 
+4
source

Slow (O(n*log(n)) and simple:

 const nearest = (arr, val) => (sorted => (indexOfVal => ({ lo: sorted[indexOfVal - 1], hi: sorted[indexOfVal + 1] }))(sorted.indexOf(val)))([...arr, val].sort()) const mapIndexOf = (obj, lookup) => Object.keys(obj).reduce( (a, v) => ({ ...a, [v]: lookup.indexOf(obj[v]) }), {} ) const scores = [0.7, 1.05, 0.81, 0.96, 3.2, 1.23] console.log(mapIndexOf(nearest(scores, 1), scores)) 
+2
source

Scroll through the array, subtract the value from your variable, compare, and then write the closest values. Here is a quick example:

 var value = 1; var scores = [0.7, 1.05, 0.81, 0.96, 3.2, 1.23]; var ret = {}; for(var i = 0, len = scores.length; i < len; i++){ var comp = scores[i] - value; if(comp > 0){ if(!ret.high){ ret.high = i; } else if(scores[i] < scores[ret.high]){ ret.high = i; } } else if(comp < 0){ if(!ret.low){ ret.low = i; } else if(scores[i] > scores[ret.low]){ ret.low = i; } } else{ ret = { low: i, high: i }; break; } } document.getElementById('result').innerHTML = 'high: '+ret.high+' low: '+ret.low; 
 <div id="result"></div> 
0
source

In this way:

 var lower = function(a,b){return a.element > b.element ? b : a; }; var higher = function(a,b){return a.element > b.element ? a : b; }; var withIndex = function(element,index){ return {element: element, index: index}; }; var nearest = function(array, limit) { var lowerValues = array.map(withIndex).filter(function(a){ return a.element<limit }); var higherValues = array.map(withIndex).filter(function(a){ return a.element>limit }); return { low: lowerValues.reduce(higher).index, high: higherValues.reduce(lower).index }; } 
0
source
 var scores=[0.7, 1.05, 0.81, 0.96, 3.2, 1.23]; var lowIndex = 0; var highIndex = 0; var currentLow = 0; var currentHigh = 0; var temp = 0; var variable = 2; for(var i = 0; i < scores.length; i++) { temp = variable - scores[i]; if((currentLow == 0) && (temp > 0)) { currentLow = temp; } if((currentHigh == 0) && (temp < 0)) { currentHigh = temp; } if((temp >= currentHigh) && (temp <= 0)) { highIndex = i; currentHigh = temp; } if((temp <= currentLow) && (temp >= 0)) { lowIndex = i; currentLow = temp; } } window.alert("Low:" + lowIndex + " High:" + highIndex); 

This code works, and you can see the logic of what is happening.

0
source
 // for storing greater values and their indeces var gtVals = { val : [], ind : [] }; // for storing lesser values and their indeces var ltVals = { val : [], ind : [] } var scores=[0.7, 1.05, 0.81, 0.96, 3.2, 1.23]; function highLow(value){ var val = parseFloat(value); for(var i = 0; i < scores.length ; i++){ if(scores[i] > val ){ gtVals.val.push(scores [i] - val ); gtVals.ind.push(i ); } else{ ltVals.val.push(val - scores[i] ); ltVals.ind.push(i ); } } var higherindex = gtVals.ind[gtVals.val.indexOf((Math.min.apply(Math, gtVals.val)))]; var lowerindex = ltVals.ind[ltVals.val.indexOf((Math.min.apply(Math, ltVals.val)))]; return { low: lowerindex, high : higherindex }; } console.log(highLow(1)); 

http://jsfiddle.net/2q572hxj/3/

-1
source

For people who like perl, assembler or regular expressions, here is the solution next to the single-line layer:

 var compV = 1; var scores=[0.7, 1.05, 0.81, 0.96, 3.2, 1.23]; for(var h=0,l=0,i=0,tmp=0,lV=Number.MAX_VALUE,hV=lV; i < scores.length; i++) { tmp=compV-scores[i];tmp>0 && tmp<lV ? (l=i,lV=tmp) : tmp<0 && -tmp<hV ? (h=i,hV=-tmp) : 0; } 

l (lowercase "L") contains the lowest value index, h (lowercase "H") contains the highest value index. Good luck :)

-1
source

Source: https://habr.com/ru/post/975311/


All Articles