我有一个从- 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。
当前回答
最有效的方法是二分查找。然而,即使是简单的解决方案,当下一个数字与当前数字进一步匹配时,也可以退出。这里几乎所有的解决方案都没有考虑到数组是有序的,并且迭代整个:/
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以返回数组中的索引。
其他回答
O(n)时间复杂度的一个更简单的方法是在数组的一次迭代中完成。此方法用于未排序的数组。
下面是一个javascript的例子,在这里我们从数组中找到最接近“58”的数字。
var inputArr = [150, 5, 200, 50, 30]; Var搜索= 58; var min = Math.min(); Var结果= 0; (我= 0;< inputArr.length; + +) { let absVal =数学。abs(search - inputArr[i]) if(min > absVal) { min = absVal; result = inputArr[i]; } } console.log(结果);//如果输入为58,则期望输出为50
这也适用于正数,负数,小数。
Math.min()将返回Infinity。
结果将存储离搜索元素最近的值。
ES6
适用于已排序和未排序数组
数字整数和浮点数,字符串欢迎
/**
* Finds the nearest value in an array of numbers.
* Example: nearestValue(array, 42)
*
* @param {Array<number>} arr
* @param {number} val the ideal value for which the nearest or equal should be found
*/
const nearestValue = (arr, val) => arr.reduce((p, n) => (Math.abs(p) > Math.abs(n - val) ? n - val : p), Infinity) + val
例子:
let values = [1,2,3,4,5]
console.log(nearestValue(values, 10)) // --> 5
console.log(nearestValue(values, 0)) // --> 1
console.log(nearestValue(values, 2.5)) // --> 2
values = [100,5,90,56]
console.log(nearestValue(values, 42)) // --> 56
values = ['100','5','90','56']
console.log(nearestValue(values, 42)) // --> 56
最有效的方法是二分查找。然而,即使是简单的解决方案,当下一个数字与当前数字进一步匹配时,也可以退出。这里几乎所有的解决方案都没有考虑到数组是有序的,并且迭代整个:/
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);
就这些!
你可以使用下面的逻辑找到最接近的数字,而不使用reduce函数
let arr = [0, 80, 10, 60, 20, 50, 0, 100, 80, 70, 1];
const n = 2;
let closest = -1;
let closeDiff = -1;
for (let i = 0; i < arr.length; i++) {
if (Math.abs(arr[i] - n) < closeDiff || closest === -1) {
closeDiff = Math.abs(arr[i] - n);
closest = arr[i];
}
}
console.log(closest);