我有一个从- 1000到+ 1000的数我有一个数组,里面都是数字。是这样的:
[2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
我想让我得到的数字变成数组中最接近的数字。
例如,我的数字是80,我希望它是82。
我有一个从- 1000到+ 1000的数我有一个数组,里面都是数字。是这样的:
[2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
我想让我得到的数字变成数组中最接近的数字。
例如,我的数字是80,我希望它是82。
当前回答
这里的另一个变体是圆形范围,从头到脚连接,只接受给定输入的最小值。这帮助我获得了一个加密算法的字符代码值。
function closestNumberInCircularRange(codes, charCode) {
return codes.reduce((p_code, c_code)=>{
if(((Math.abs(p_code-charCode) > Math.abs(c_code-charCode)) || p_code > charCode) && c_code < charCode){
return c_code;
}else if(p_code < charCode){
return p_code;
}else if(p_code > charCode && c_code > charCode){
return Math.max.apply(Math, [p_code, c_code]);
}
return p_code;
});
}
其他回答
对于排序数组(线性搜索)
到目前为止,所有答案都集中在搜索整个数组上。 考虑到你的数组已经排序,你真的只想要最近的数字,这可能是最简单的(但不是最快的)解决方案:
var a = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]; var target = 90000; /** * Returns the closest number from a sorted array. **/ function closest(arr, target) { if (!(arr) || arr.length == 0) return null; if (arr.length == 1) return arr[0]; for (var i = 1; i < arr.length; i++) { // As soon as a number bigger than target is found, return the previous or current // number depending on which has smaller difference to the target. if (arr[i] > target) { var p = arr[i - 1]; var c = arr[i] return Math.abs(p - target) < Math.abs(c - target) ? p : c; } } // No number in array is bigger so return the last. return arr[arr.length - 1]; } // Trying it out console.log(closest(a, target));
请注意,该算法可以大大改进,例如使用二叉树。
所有的解决方案都是过度设计的。
它是如此简单:
const needle = 5;
const haystack = [1, 2, 3, 4, 5, 6, 7, 8, 9];
haystack.sort((a, b) => {
return Math.abs(a - needle) - Math.abs(b - needle);
})[0];
// 5
最有效的方法是二分查找。然而,即使是简单的解决方案,当下一个数字与当前数字进一步匹配时,也可以退出。这里几乎所有的解决方案都没有考虑到数组是有序的,并且迭代整个:/
const closest = (orderedArray, value, valueGetter = item => item) => orderedArray.find((item, i) => i === orderedArray.length - 1 || Math.abs(value - valueGetter(item)) < Math.abs(value - valueGetter(orderedArray[i + 1]))); var data = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]; console.log('21 -> 2', closest(data, 21) === 2); console.log('22 -> 42', closest(data, 22) === 42); // equidistant between 2 and 42, select highest console.log('23 -> 42', closest(data, 23) === 42); console.log('80 -> 82', closest(data, 80) === 82);
这也可以在非原语上运行,例如,nearest (data, 21, item => item.age)
将find更改为findIndex以返回数组中的索引。
我不知道我是否应该回答一个老问题,但由于这篇文章首先出现在谷歌搜索中,我希望你能原谅我在这里添加我的解决方案和我的2c。
由于懒惰,我无法相信这个问题的解决方案会是一个LOOP,所以我搜索了更多,并返回了过滤器函数:
var myArray = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];
var myValue = 80;
function BiggerThan(inArray) {
return inArray > myValue;
}
var arrBiggerElements = myArray.filter(BiggerThan);
var nextElement = Math.min.apply(null, arrBiggerElements);
alert(nextElement);
就这些!
ES5版本:
Var计数= [4,9,15,6,2], 目标= 5; Var最接近=计数。Reduce(函数(prev, curr) { 返回(数学。abs(curr - goal) <数学。腹肌(前一球)?Curr: prev); }); console.log(最近的);