Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从数组中获取最接近的数字_Javascript_Arrays - Fatal编程技术网

Javascript 从数组中获取最接近的数字

Javascript 从数组中获取最接近的数字,javascript,arrays,Javascript,Arrays,我有一个从-1000到+1000的数字,我有一个包含数字的数组。像这样: [2, 42, 82, 122, 162, 202, 242, 282, 322, 362] 我想把我得到的数字改成数组中最接近的数字 例如,我得到80作为数字,我希望它得到82在数组上稍微修改一下二进制搜索就可以了。对于小范围,最简单的方法是有一个map数组,例如,使用您的示例,第80个条目中的值为82。对于一个更大、更稀疏的范围,可能需要进行二进制搜索 使用查询语言,您可以在输入号码的两侧查询一定距离的值,然后对结果

我有一个从-1000到+1000的数字,我有一个包含数字的数组。像这样:

[2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
我想把我得到的数字改成数组中最接近的数字


例如,我得到
80
作为数字,我希望它得到
82

在数组上稍微修改一下二进制搜索就可以了。

对于小范围,最简单的方法是有一个map数组,例如,使用您的示例,第80个条目中的值为82。对于一个更大、更稀疏的范围,可能需要进行二进制搜索


使用查询语言,您可以在输入号码的两侧查询一定距离的值,然后对结果的缩减列表进行排序。但是SQL没有“下一步”或“上一步”的好概念,无法为您提供“干净”的解决方案。

以下是伪代码,可以转换为任何过程语言:

array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
number = 112
print closest (number, array)

def closest (num, arr):
    curr = arr[0]
    foreach val in arr:
        if abs (num - val) < abs (num - curr):
            curr = val
    return curr
作为概念证明,下面是我用来展示这一点的Python代码:

def closest (num, arr):
    curr = arr[0]
    for index in range (len (arr)):
        if abs (num - arr[index]) < abs (num - curr):
            curr = arr[index]
    return curr

array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
number = 112
print closest (number, array)
<html>
    <head></head>
    <body>
        <script language="javascript">
            function closest (num, arr) {
                var curr = arr[0];
                var diff = Math.abs (num - curr);
                for (var val = 0; val < arr.length; val++) {
                    var newdiff = Math.abs (num - arr[val]);
                    if (newdiff < diff) {
                        diff = newdiff;
                        curr = arr[val];
                    }
                }
                return curr;
            }
            array = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362];
            number = 112;
            alert (closest (number, array));
        </script>
    </body>
</html>

正如上面所述,对于小数据集或不需要盲目快速的事物,这不应该有很大区别,但这是一个你可能需要考虑的选项。

< P>工作代码如下:

var数组=[2,42,82,122,162,202,242,282,322,362];
函数最近(数组,num){
var i=0;
var-minDiff=1000;
var ans;
for(数组中的i){
var m=Math.abs(num-array[i]);
if(mES5版本:

var计数=[4,9,15,6,2],
目标=5;
var最近=计数。减少(功能(上一个,当前){
返回(Math.abs(curr-goal)控制台日志(最近)我不知道我是否应该回答一个老问题,但由于这篇文章首先出现在谷歌搜索上,我希望您能原谅我在这里添加我的解决方案&2c

由于懒惰,我不敢相信这个问题的解决方案会是一个循环,所以我搜索了更多,并返回了:

就这些

对于排序数组(线性搜索) 到目前为止,所有的答案都集中在搜索整个数组。 考虑到您的数组已经排序,并且您确实只需要最接近的数字,这可能是最快的解决方案:

var a=[2,42,82,122,162,202,242,282,322,362];
var目标=90000;
/**
*返回排序数组中最接近的数字。
**/
功能最近(arr,目标){
如果(!(arr)| arr.length==0)
返回null;
如果(arr.length==1)
返回arr[0];
对于(变量i=1;i目标){
var p=arr[i-1];
var c=arr[i]
返回Math.abs(p-target)日志(最近的(a,目标))我对一个类似问题的回答是,也考虑了关系,它是纯Javascript,尽管它不使用二进制搜索,所以它是O(N)而不是O(logN):

var searchArray=[0,30,60,90];
var元素=33;
函数findClosest(数组,元素){
var minDelta=null;
var minIndex=null;
对于(var i=0;i

ES6(ECMAScript 2015)版本:

const counts=[4,9,15,6,2];
常数目标=5;
const output=counts.reduce((当前,当前)=>Math.abs(当前目标)console.log(output);
我喜欢Fusion的方法,但其中有一个小错误。就像这样,它是正确的:

    function closest(array, number) {
        var num = 0;
        for (var i = array.length - 1; i >= 0; i--) {
            if(Math.abs(number - array[i]) < Math.abs(number - array[num])){
                num = i;
            }
        }
        return array[num];
    }
我用
console.time()
测试了它,它比其他函数稍快。

适用于未排序的数组 虽然这里发布了一些很好的解决方案,但JavaScript是一种灵活的语言,它为我们提供了以多种不同方式解决问题的工具。 当然,这一切都取决于你的风格。如果你的代码功能更强大,你会找到合适的代码,即:

  arr.reduce(function (prev, curr) {
    return (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);
  });
与使用
Math.min.apply
查找最小值相反,此函数不需要对输入数组
arr
进行排序。我们不需要关心索引或事先对其进行排序。

为了清楚起见,我将逐行解释代码:

  • arr.map(函数(k){return Math.abs(k-x)})
    创建一个新数组,基本上存储给定数字的绝对值(arr
    arr
    中的数字)减去输入数字(
    x
    )。接下来我们将查找最小的数字(也是最接近输入数字的)
  • Math.min.apply(Math,indexArr)
    这是在我们刚刚创建的数组中查找最小数的合法方法(仅此而已)
  • arr[indexArr.indexOf(min)]
    这可能是最有趣的部分。我们已经找到了最小的数字,但我们不确定是否应该加上或减去初始数字(
    x
    )。这是因为我们使用了
    Math.abs()
    来找到差异。然而,
    array.map
    创建了(逻辑上的)输入数组的映射,使索引保持在同一位置。因此,要找到最接近的数字,我们只需返回给定数组中找到的最小值的索引
    indexArr.indexOf(min)
  • 我已经创建了一个演示程序。

    此解决方案使用ES5,如果满足条件,它允许停止迭代

    相反,它不需要为一个结果迭代所有元素

    在回调内部,获取搜索值和实际
    之间的绝对
    增量
    ,并与上一个增量进行比较。如果大于或等于,则迭代停止,因为所有其他值及其增量都大于实际值

    如果c中的
    delta
    0  1  2   3   4   5   6   7   8   9  <- indexes
    2 42 82 122 162 202 242 282 322 362  <- values
    L             M                   H  L=0, H=9, M=4, 162 higher, H<-M
    L     M       H                      L=0, H=4, M=2, 82 lower/equal, L<-M
          L   M   H                      L=2, H=4, M=3, 122 higher, H<-M
          L   H                          L=2, H=3, difference of 1 so exit
              ^
              |
              H (122-112=10) is closer than L (112-82=30) so choose H
    
    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);
    
    var searchArray= [0, 30, 60, 90];
    var element= 33;
    
    function findClosest(array,elem){
        var minDelta = null;
        var minIndex = null;
        for (var i = 0 ; i<array.length; i++){
            var delta = Math.abs(array[i]-elem);
            if (minDelta == null || delta < minDelta){
                minDelta = delta;
                minIndex = i;
            }
            //if it is a tie return an array of both values
            else if (delta == minDelta) {
                return [array[minIndex],array[i]];
            }//if it has already found the closest value
            else {
                return array[i-1];
            }
    
        }
        return array[minIndex];
    }
    var closest = findClosest(searchArray,element);
    
        function closest(array, number) {
            var num = 0;
            for (var i = array.length - 1; i >= 0; i--) {
                if(Math.abs(number - array[i]) < Math.abs(number - array[num])){
                    num = i;
                }
            }
            return array[num];
        }
    
        var getClosest = function(number, array) {
            var current = array[0];
            var difference = Math.abs(number - current);
            var index = array.length;
            while (index--) {
                var newDifference = Math.abs(number - array[index]);
                if (newDifference < difference) {
                    difference = newDifference;
                    current = array[index];
                }
            }
            return current;
        };
    
      arr.reduce(function (prev, curr) {
        return (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);
      });
    
      var findClosest = function (x, arr) {
        var indexArr = arr.map(function(k) { return Math.abs(k - x) })
        var min = Math.min.apply(Math, indexArr)
        return arr[indexArr.indexOf(min)]
      }
    
      findClosest(80, [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]) // Outputs 82
    
    if (delta >= lastDelta) {
    
    if (delta > lastDelta) {
    //       ^^^ without equal sign
    
    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;
      });
    }
    
    package com.algo.closestnumberinarray;
    import java.util.TreeMap;
    
    
    public class Find_Closest_Number_In_Array {
    
        public static void main(String arsg[]) {
            int array[] = { 1, 60, 0, -10, 100, 87, 69 };
            int number = 56;
            int num = getClosestNumber(array, number);
            System.out.println("Number is=" + num);
        }
    
        public static int getClosestNumber(int[] array, int number) {
            int diff[] = new int[array.length];
    
            TreeMap<Integer, Integer> keyVal = new TreeMap<Integer, Integer>();
            for (int i = 0; i < array.length; i++) {
    
                if (array[i] > number) {
                    diff[i] = array[i] - number;
                    keyVal.put(diff[i], array[i]);
                } else {
                    diff[i] = number - array[i];
                    keyVal.put(diff[i], array[i]);
                }
    
            }
    
            int closestKey = keyVal.firstKey();
            int closestVal = keyVal.get(closestKey);
    
            return closestVal;
        }
    }
    
    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
    
    #include <algorithm>
    #include <iostream>
    #include <cmath>
    
    using namespace std;
    
    class CompareFunctor
    {
    
    public:
        CompareFunctor(int n) { _n = n; }
        bool operator()(int & val1, int & val2)
        {
            int diff1 = abs(val1 - _n);
            int diff2 = abs(val2 - _n);
            return (diff1 < diff2);
        }
    
    private:
        int _n;
    };
    
    int Find_Closest_Value(int nums[], int size, int n)
    {
        CompareFunctor cf(n);
        int cn = *min_element(nums, nums + size, cf);
        return cn;
    }
    
    int main()
    {
        int nums[] = { 2, 42, 82, 122, 162, 202, 242, 282, 322, 362 };
        int size = sizeof(nums) / sizeof(int);
        int n = 80;
        int cn = Find_Closest_Value(nums, size, n);
        cout << "\nClosest value = " << cn << endl;
        cin.get();
    }
    
    function findTwoClosest(givenList, goal) {
      var first;
      var second;
      var finalCollection = [givenList[0], givenList[1]];
      givenList.forEach((item, firtIndex) => {
        first = item;
    
        for (let i = firtIndex + 1; i < givenList.length; i++) {
          second = givenList[i];
    
          if (first + second < goal) {
            if (first + second > finalCollection[0] + finalCollection[1]) {
              finalCollection = [first, second];
            }
          }
        }
      });
    
      return finalCollection;
    }
    
    var counts = [2, 42, 82, 122, 162, 202, 242, 282, 322, 362]
    var goal = 80;
    console.log(findTwoClosest(counts, goal));
    
    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