Quiero probar un valor acumulado (var goal) de algunos campos de entrada con el valor más alto más cercano ['size'] en una matriz.

Entonces, supongamos que mi objetivo es encontrar el valor más alto más cercano a size 95.

var variants = [
          { value: "128428226", size: "50 ", price: 3.72, priceIncl: 4.5 },
          { value: "128428229", size: "100 ", price: 5.5, priceIncl: 6.65 },
          { value: "128428232", size: "150 ", price: 7.27, priceIncl: 8.8 }
    ]

var goal = 95; 
var closest = variants;
var closestPrice = '';
var closestPriceIncl = '';
var closestVal = '';


 $.each(variants, function(){
          if (closest['size'] == null || Math.abs(this['size'] - goal) < Math.abs(closest['size'] - goal)) { 
            closest = this;
            closestPrice = closest['price'];
            closestPriceIncl = closest['priceIncl'];
            closestVal = closest['value']
          }
        });    

Soy capaz de obtener todos los valores que quiero. Sin embargo, cuando el objetivo es algo como 75, mi script selecciona los valores de size: "50". Entonces, cuando el objetivo es 51, debería seleccionar 100, etc.

Realmente no puedo encontrar una manera de hacer eso. Encontré algunas otras respuestas que usan una función pero luego no entiendo cómo obtener los otros valores. (Simplemente necesito encontrar el valor más alto más cercano). Cualquier ayuda es muy apreciada.

1
Meules 1 mar. 2018 a las 19:14

3 respuestas

La mejor respuesta

Si entiendo su problema correctamente, el siguiente código debería ser suficiente:

    var variants = [
    { value: "128428226", size: "50 ", price: 3.72, priceIncl: 4.5 },
    { value: "128428229", size: "100 ", price: 5.5, priceIncl: 6.65 },
    { value: "128428232", size: "150 ", price: 7.27, priceIncl: 8.8 }
];

var goal = 51;

var closest = null ;
var minDiff = Number.MAX_SAFE_INTEGER;
for(var index in variants){
    var valueObject = variants[index];
    if(valueObject.size > goal){
        var diff = Math.abs(valueObject.size - goal);
        if(diff < minDiff){
            closest = valueObject;
            minDiff = diff;
        }
    }
}
console.log(minDiff);
console.log(closest);

Los dos predicados definitorios son que la variante más cercana tiene un tamaño mayor que el objetivo y que la diferencia entre los tamaños debe ser mínima.

2
Alon Gadot 1 mar. 2018 a las 16:30

Prueba con esto. Creo que esto debe ser lo que estás intentando hacer.

var variants = [
          { value: "128428226", size: "50 ", price: 3.72, priceIncl: 4.5 },
          { value: "128428229", size: "100 ", price: 5.5, priceIncl: 6.65 },
          { value: "128428232", size: "150 ", price: 7.27, priceIncl: 8.8 }
    ];

var arr = Object.keys(variants).map(function(k) { return parseInt(variants[k]['size']) });

function closest(array,num){
    var i=0;
    var minDiff=1000;
    var ans;
    for(i in array){
         var m=Math.abs(num-array[i]);
         if(m<minDiff){ 
                minDiff=m; 
                ans=array[i]; 
            }
      }
    return ans;
}

console.log(closest(arr,75))
0
AdhershMNair 1 mar. 2018 a las 16:33

Puede usar el delta absoluto del elemento y el resultado temporal anterior de stire y, si es más pequeño, luego empujar una nueva matriz, de lo contrario, verificar si el delta es el mismo, luego empujar el elemento real al conjunto de resultados.

Como resultado, se devuelve una matriz con los elementos más cercanos.

Tal vez sea una buena idea y limpie los datos del espacio de valores agregado, como size: "50 ".

var variants = [{ value: "128428226", size: "50", price: 3.72, priceIncl: 4.5 }, { value: "128428229", size: "100", price: 5.5, priceIncl: 6.65 }, { value: "128428232", size: "150", price: 7.27, priceIncl: 8.8 }],
    goal = 95,
    closest = variants.reduce(function (r, o) {
        if (!r || Math.abs(o.size - goal) < Math.abs(r[0].size - goal)) {
            return [o];
        }
        if (Math.abs(o.size - goal) === Math.abs(r[0].size - goal)) {
            return r.push(o);
        }
        return r;
    }, undefined);
    
console.log(closest);
0
Nina Scholz 1 mar. 2018 a las 16:46