0

私は次のようなものを持っています

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

newVar = 76;

配列内のどのキーの値が (一度数値化された後) 私の newVar に最も近いかを見つけるにはどうすればよいですか? 23、58、172 のうちどれが私の 76 に最も近いですか?

ありがとう

4

4 に答える 4

1

まず、技術的にオブジェクトを作成しているので、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;
        }
    }
}

forループが完了するclosest.keyと、 に最も近い一致のインデックスが含まれますnewVar。保護を強化するために、 を使用hasOwnPropertyして、プロトタイプの 1 つのプロパティを誤って反復処理しないようにしますkeyVals(この特定のシナリオでは、そうなる可能性はほとんどありません)。

于 2012-08-16T14:16:33.310 に答える
0

まず第一に、
数値型の値をキーとして使用している場合、それらは数値のままでなければなりません。
'23' ではなく 23 にする必要があります。
そうしないと、23 は文字列 '23' として扱われ、数値に対して数学的にテストできません。

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

最も近いキーを見つけるには、
キーをループして最も近いキーを検索します。

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
于 2012-08-16T14:14:04.703 に答える
0

他の人が指摘しているように、Objects(別名ハッシュ) は、キーを値にマップするときに使用するのに最適なデータ構造です。これを念頭に置いて、マップ キーを数値順に並べ替えると、パフォーマンスが向上します。

// 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];
}

明らかに、keyValsマップが小さい (1000 エントリ未満) 場合、この種の最適化は非常に学術的です (それでも非常に楽しい) :)

于 2012-08-16T14:30:16.933 に答える
0

ただし、 に最も近い 2 つの値が存在する可能性があることに注意してnewVarください。

例えば:

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

23 と 129 の両方が 76 に最も近いです。

それで、

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);

「76に最も近いキーは[23,129]で、差は53です」と警告します

またはあなたの配列で、

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

「76に最も近いキーは[58]で、差は18です」と警告します

于 2012-08-16T14:25:55.647 に答える