4

我正在使用一个 javascript 对象,虽然我有一个解决方案,但我不禁认为它可以更有效地完成。

该对象是从对 php 脚本的 ajax 调用返回的

r.price_array[1] = 39.99
r.price_array[5] = 24.99
r.price_array[10] = 19.99
and so on....

我现在正在做的是在键值之间搜索(键值代表一个数量)

qty = $(this).val();

if (qty >= 1 && qty <= 4){
    price_set = 1;
}
else if (qty >= 5 && qty <= 9){
    price_set = 15;
}
else if (qty >= 10 && qty <= 14){
    price_set = 25;
}

//等等...

console.log(r.price_array[price_set]); //this returns the value

有没有办法获取 3 的数量并找到下一个最低的键匹配,即 1?或数量 7 并找到关键 5?

4

6 回答 6

2

当然 - 只需使用循环:

var price_array = {
    1: 39.99,
    5: 24.99,
   10: 19.99,
   15: 15.99,
   20: 10.99,
   25:  5.99,
   30:  0.99
}
var qty = 12;

var maxKey = -1;
for (var key in price_array) {
    if (maxKey < 0 || key < qty) {
        maxKey = Math.max(maxKey, key);
    }
}
console.log(maxKey); //10
console.log(price_array[maxKey]); //19.99
于 2013-08-23T19:50:45.277 回答
2

我的版本(经过测试,小提琴在这里:http: //jsfiddle.net/fred02138/UZTbJ/):

// assume keys in rprice object are sorted integers
function x(rprice, qty) {
    var prev = -1;
    var i;
    for (i in rprice) {
        var n = parseInt(i);
        if ((prev != -1) && (qty < n))
            return prev;
        else 
            prev = n;
    }    
}

var rprice = {
    1: 39.99,
    5: 24.99,
    10: 19.99
}

alert(x(rprice, 3));
alert(x(rprice, 7));
于 2013-08-23T20:10:17.173 回答
1

另一种方法,在这个 Fiddle中演示:

var lowerKeyFinder = function(prices) {
    var keys = Object.keys(prices);
    keys.sort(function(a, b) {return a - b;});

    return function(val) {
        var maxKey = -1;
        for (var i = 0, len = keys.length; i < len; i++) {
            if (maxKey < 0 || keys[i] < val) {
                maxKey = Math.max(maxKey, keys[i]);
            }
        }
        return maxKey;
    };
};

var lookup = lowerKeyFinder(r.price_array);

lookup(3);  //=> 1
lookup(7);  //=> 5

这并不坚持键最初是按顺序呈现的,而是对它们进行一次排序。它建立在@h2ooooooo 的答案之上,但工作方式略有不同,因为它最终提供了一个简单的按数量查找的功能。

于 2013-08-23T20:40:14.867 回答
0

这是执行此操作的函数。它希望用于具有数字键的对象,例如您的数组:

function getClosestKey(arr, target, u){
  if(arr.hasOwnProperty(target))
    return target;

  var keys = Object.keys(arr);
  keys.sort(function(a,b){ return a-b; });

  // Can replace linear scan with Binary search for O(log n) search
  // If you have a lot of keys that may be worthwhile
  for(var i = 0, prev; i < keys.length; i++){
    if(keys[i] > target)
      return prev === u ? u : +prev;
    prev = keys[i];
  }
  return +keys[i - 1];
}

您必须在旧浏览器中使用 SHIM Object.keys:

Object.keys = Object.keys || function(obj){
  var result = [];
  for(var key in obj)
    if(obj.hasOwnProperty(key)) result.push(key);
  return result;
}

用法:

var price_array = [];
price_array[1] = 39.99;
price_array[5] = 24.99;
price_array[10] = 19.99;

getClosestKey(price_array, 0); // undefined
getClosestKey(price_array, 1); // 1
getClosestKey(price_array, 3); // 1
getClosestKey(price_array, 4); // 1
getClosestKey(price_array, 5); // 5
getClosestKey(price_array, 7); // 5
getClosestKey(price_array, 9); // 5
getClosestKey(price_array, 10); // 10
getClosestKey(price_array, 100); // 10
于 2013-08-23T19:54:44.843 回答
0

Math.round()您可以使用和一些简单的除法四舍五入到最接近的 5 倍数:

var price_array = {};
price_array[1] = 39.99;
price_array[5] = 24.99;
price_array[10] = 19.99;

function qty_round(qty) {
  // Math.max() is used to enforce a minimum quantity of 1
  return Math.max(1, 5 * Math.round(qty / 5));
}

console.log(price_array[qty_round(1)]);  // 39.99
console.log(price_array[qty_round(4)]);  // 24.99
console.log(price_array[qty_round(9)]);  // 19.99
console.log(price_array[qty_round(10)]); // 19.99

通过一些小的修改,您可以向下取整而不是向上取整(使用Math.floor代替Math.round)或强制执行最大数量。

于 2013-08-23T19:59:23.143 回答
0

另一种解决方案是使用 for-in 循环。一旦找到价值,它就有破坏的好处。

/**
 * @param {object} object - object with sorted integer keys
 * @param {number} index - index to look up
 */
function getValueForLowestKey(object, index) {
    let returned;

    for (const key in object) {
        if(key > index) break;
        returned = object[key];
    }

    return returned;
}
于 2022-01-23T15:22:21.583 回答