我有一个从- 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。
当前回答
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
其他回答
其他答案建议你需要遍历整个数组:
计算每个元素的偏差 跟踪最小偏差及其元素 最后,在遍历整个数组后,返回具有最小偏差的元素。
如果数组已经排序了,那就没有意义了。没有必要计算所有的偏差。例如,在一个100万个元素的有序集合中,你只需要计算~19个偏差(最多)来找到你的匹配。你可以用二进制搜索方法来实现:
function findClosestIndex(arr, element) {
let from = 0, until = arr.length - 1
while (true) {
const cursor = Math.floor((from + until) / 2);
if (cursor === from) {
const diff1 = element - arr[from];
const diff2 = arr[until] - element;
return diff1 <= diff2 ? from : until;
}
const found = arr[cursor];
if (found === element) return cursor;
if (found > element) {
until = cursor;
} else if (found < element) {
from = cursor;
}
}
}
结果:
console.log(findClosestIndex([0, 1, 2, 3.5, 4.5, 5], 4));
// output: 3
console.log(findClosestIndex([0, 1, 2, 3.49, 4.5, 5], 4));
// output: 4
console.log(findClosestIndex([0, 1, 2, 3.49, 4.5, 5], 90));
// output: 5
console.log(findClosestIndex([0, 1, 2, 3.49, 4.5, 5], -1));
// output: 0
最有效的方法是二分查找。然而,即使是简单的解决方案,当下一个数字与当前数字进一步匹配时,也可以退出。这里几乎所有的解决方案都没有考虑到数组是有序的,并且迭代整个:/
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以返回数组中的索引。
ES5版本:
Var计数= [4,9,15,6,2], 目标= 5; Var最接近=计数。Reduce(函数(prev, curr) { 返回(数学。abs(curr - goal) <数学。腹肌(前一球)?Curr: prev); }); console.log(最近的);
ES6(2015年ECMAScript)版本:
Const counts = [4,9,15,6,2]; Const goal = 5; Const输出=计数。reduce((prev, curr) =>abs(curr - goal) <数学。腹肌(前一球)?Curr: prev); console.log(输出);
为了可重用性,您可以封装一个支持占位符的curry函数(http://ramdajs.com/0.19.1/docs/#curry或https://lodash.com/docs#curry)。这提供了很大的灵活性,取决于你需要什么:
const getnearest = _。Curry((计数,目标)=> { 返回计数。reduce((prev, curr) =>abs(curr - goal) <数学。腹肌(前一球)?Curr: prev); }); const closestToFive = getnearest (_, 5); const output = closestToFive([4,9,15,6,2]); console.log(输出); < script src = " https://cdn.jsdelivr.net/npm/lodash@4.17.20 lodash.min.js " > < /脚本>
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