简体   繁体   English

javascript:如何在最接近值的关联数组中查找键?

[英]javascript: how to find the key in an associative array that is closest to a value?

i have something like 我有类似的东西

var keyVals = Array;
keyVals['23'] = 234;
keyVals['58'] = 'sunshine';
keyVals['172'] = 'lolipops';

newVar = 76;

how can i find which of the keys in the array is closest in value (once made into numbers) to my newVar? 我怎样才能找到数组中哪个键的值(一旦被数字化)最接近newVar? which of 23, 58, 172 is closest to my 76? 23、58、172中哪一个最接近我的76岁?

thanks 谢谢

First, a note that you're technically creating an object, so the preferred assignment for keyVals would be keyVals = {} . 首先,请注意,您实际上是在创建对象,因此keyVals的首选分配是keyVals = {}

var newVar = 31,
    keyNum,
    key,
    diff,
    keyVals = {},
    closest = {
        key: null,
        diff: null
    };

keyVals['23'] = 234;
keyVals['58'] = 'sunshine';
keyVals['172'] = 'lolipops';

for(key in keyVals) {
    if(keyVals.hasOwnProperty(key)) {
        keyNum = parseInt(key,10);
        diff = Math.abs(newVar - keyNum);

        if(!closest.key || diff < closest.diff) {
            closest.key = key;
            closest.diff = diff;
        }
    }
}

When the for loop is complete, closest.key will contain the index of the nearest match to newVar . for循环完成时, closest.key将包含与newVar最接近的匹配项的索引。 For added protection, use hasOwnProperty to make sure you don't accidentally iterate over a property of one of keyVals prototypes (granted, that's pretty unlikely in this specific scenario). 为了提供额外的保护,请使用hasOwnProperty来确保您不会意外地迭代keyVals原型之一的属性(当然,在这种特定情况下,这不太可能发生)。

First of all: 首先:
If you're using number-type values as your keys, they must remain numbers. 如果您使用数字类型的值作为键,则它们必须保留数字。
It should be 23, not '23' 应该是23,而不是“ 23”
Otherwise 23 will be treated as the string '23', which cannot be mathematically tested against a number. 否则,23将被视为字符串'23',无法对数字进行数学测试。

var keyVals = Array;
keyVals[23] = 234; // keyVals[23], not keyVals['23']
keyVals[58] = 'sunshine';
keyVals[172] = 'lolipops'

To find the closest key, 要找到最接近的键,
Just loop through your keys and search for the closest one. 只需循环浏览您的按键并搜索最接近的按键即可。

dist = Number.POSITIVE_INFINITY; // set the distance from key to value
closestkey = -1; // closest key variable
for(i in keyVals) {
    // i is the key, keyVals[i] is the value
    newdist = Math.abs(newVar - i); // distance from current key to value
    if (newdist < dist) {
        // we found a key closer to the value
        dist = newdist; // set new smallest distance
        closestkey = i; // set the value to the current key
    }
}
// Now closestkey is the key to your closest variable

But be aware that there can be 2 values which are the closest to newVar . 但是请注意,可能存在2个最接近newVar

For example: 例如:

keyVals[23] = 234;
keyVals[129] = 'aaa';
keyVals[172] = 'lolipops';

Both 23 and 129 are the closest to 76. 23和129最接近76。

Then, 然后,

var keyVals = Array;
keyVals[23] = 234;
keyVals[129] = 'aaa';
keyVals[172] = 'lolipops';
newVar = 76;
var closest=new Object();
for(var i in keyVals){
    if(typeof closest.dif=='undefined'){
        closest.dif=Math.abs(newVar-i);
        closest.val=[i];
    }else{
        if(closest.dif==Math.abs(newVar-i)){
            closest.val.push(i);
        }else if(closest.dif>Math.abs(newVar-i)){
            closest.dif=Math.abs(newVar-i);
            closest.val=[i];
        }
    }
}
alert("The closest keys to "+newVar+" are ["+closest.val.join(',')+"], with a difference of "+closest.dif);

will alert "The closest keys to 76 are [23,129], with a difference of 53" 将警告“最接近76的键是[23,129],相差53”

Or with your array, 或与您的阵列,

keyVals[23] = 234;
keyVals[58] = 'sunshine';
keyVals[172] = 'lolipops';

will alert "The closest keys to 76 are [58], with a difference of 18" 会提示“最接近76的键是[58],相差18”

As others have pointed out, Objects (aka hashes) are the best data-structure to use when you want to map a key to a value; 正如其他人指出的那样,当您想将键映射到值时, Objects (又称为哈希)是最好的数据结构。 with that in mind you will see a performance benefit for pre-sorting the maps keys into numeric order. 考虑到这一点,您将看到将映射键按数字顺序预先排序的性能优势。

// Helper method, you could also use underscore.js's `_.keys`
function getKeys(object) {
    var keys = [];
    for (var key in object) {
        if (object.hasOwnProperty(key)) {
            keys.push(key);
        }
    }
    return keys;
};

// Lookup table.
var keyVals = {
    23: "234",
    58: "sunshine",
    172: "lollypops"
};

// Extract the keys from the lookup table and sort them into numerical order.
var sortedKeys = getKeys(keyVals).sort(function (a, b) {
    return a - b;
});

// Returns the closest key in the `keyVals` lookup table for the supplied value.
function getClosestIndex(value) {
    var i;

    // Walk through the sorted keys array and stop when the next value is greater.
    for (i = 0; i < sortedKeys.length; i++) {
        if (sortedKeys[i] > value) {

            // Either return the previous key, or zero if this was the first.
            return (i === 0) ? sortedKeys[0] : sortedKeys[i - 1];
        }
    } 

    // We reached the end, so the value is greater than the highest key we have.
    return sortedKeys[i];
}

Obviously, if your keyVals map is small (under 1000 entries) then this sort of optimisation is pretty academic (but still quite fun) :) 显然,如果您的keyVals映射很小(少于1000个条目),那么这种优化是相当学术的(但仍然很有趣):)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM