从按对象标识符分组的列表中查找 Min/Max 个值

Find Min/Max Values from List grouped by Object Identifier

我正在尝试找出一组具有相同属性的项目中的最大值和最小值。例如,从屏幕截图来看,crop: 18157 的最大值为 1.77,最小值为 1.68

JsFiddle: https://jsfiddle.net/kf3qhsge/

var myCrops = new Object();

for(i=0;i<crops.length;i++){
    if(crops[i]==crops[i+1]){
        var c = crops[i];
        var n = values[i];
        myCrops[i] = {"crop":c,"value":n};
    }

} 

这在时间和 space 复杂性上都比这里的其他解决方案更简单*:

var crops  = [18002, 18154, 18154, 18155, 18155, 18155, 18156, 18156, 18156, 18156, 18157, 18157, 18157, 18157, 18157, 18158, 18158, 18158, 18158, 18158, 18158, 18159, 18159, 18159, 18159, 18159, 18159, 18159, 18160, 18160, 18160, 18160, 18160, 18160, 18160, 18160, 18160, 18161, 18161, 18161, 18161, 18161, 18161, 18161, 18161, 18161, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18165, 18165, 18165, 18165, 18165, 18165, 18165, 18165, 18165, 18165, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18170, 18170, 18170, 18170, 18170, 18170, 18170, 18170, 18170, 18171, 18171, 18171, 18171, 18171, 18171, 18171, 18171, 18171, 18171, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18173, 18173, 18173, 18173, 18173, 18173, 18173, 18173, 18173, 18173, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18176, 18176, 18176, 18176, 18176];
var values = [1.69, 1.65, 1.75, 1.7, 1.7, 1.78, 1.69, 1.62, 1.75, 1.74, 1.7, 1.72, 1.68, 1.77, 1.7, 1.62, 1.74, 1.69, 1.82, 1.68, 1.64, 1.66, 1.74, 1.57, 1.7, 1.7, 1.6, 1.66, 1.72, 1.47, 1.52, 1.7, 1.63, 1.67, 1.69, 1.7, 1.51, 1.49, 1.58, 1.63, 1.66, 1.68, 1.39, 1.71, 1.61, 1.62, 1.41, 1.52, 1.46, 1.41, 1.61, 1.65, 1.36, 1.59, 1.65, 1.64, 1.72, 1.52, 1.35, 1.49, 1.65, 1.32, 1.37, 1.69, 1.62, 1.63, 1.7, 1.72, 1.7, 1.3, 1.47, 1.56, 1.5, 1.67, 1.41, 1.73, 1.71, 1.67, 1.58, 1.73, 1.56, 1.66, 1.73, 1.57, 1.69, 1.58, 1.73, 1.47, 1.7, 1.8, 1.61, 1.77, 1.79, 1.63, 1.56, 1.58, 1.59, 1.84, 1.64, 1.77, 1.63, 1.7, 1.76, 1.73, 1.83, 1.63, 1.44, 1.32, 1.74, 1.46, 1.57, 1.67, 1.4, 1.64, 1.69, 1.58, 1.76, 1.69, 1.58, 1.72, 1.43, 1.7, 1.34, 1.69, 1.64, 1.6, 1.68, 1.5, 1.69, 1.5, 1.76, 1.47, 1.7, 1.63, 1.49, 1.48, 1.15, 1.59, 1.65, 1.6, 1.46, 1.43, 1.52, 1.55, 1.63, 1.41, 1.66, 1.62, 1.66, 1.66, 1.68, 1.63, 1.66, 1.59, 1.34, 1.67, 1.68, 1.46, 1.66, 1.77, 1.71, 1.71, 1.6, 1.47, 1.71, 1.75, 1.6, 1.58, 1.35, 1.72, 1.77, 1.68, 1.64, 1.71, 1.59, 1.63, 1.74, 1.39, 1.59, 1.71, 1.72, 1.25, 1.65, 1.7, 1.67, 1.71, 1.67, 1.49, 1.69, 1.36, 1.53, 1.73, 1.57, 1.58, 1.7, 1.61, 1.61, 1.7, 1.62, 1.69];

var myCrops = {};
for (i = 0; i < crops.length; i++) {
    
    var c = crops[i];
    if (c in myCrops) {

        var v = myCrops[c];

        if (values[i] > v.max)
            myCrops[c].max = values[i];
        if (values[i] < v.min)
            myCrops[c].min = values[i];
    }
    else {
        myCrops[c] = { min: values[i], max: values[i] };
    } 
}


console.log("Min/Max for crop 18157:\n", myCrops[18157]);

console.log("Min/Max for all crops:\n", myCrops);

myCrops[18157] 的输出:

{min: 1.68, max: 1.77}

  • 我发帖的时候还有其他解决方案,效率不高,发完后被发帖者删掉了。具有讽刺意味的是,在他们删除他们的答案之前,他们对我的答案投了反对票。

您可以使用reduce

思路是

  • 遍历作物并将其用作 op 对象的键。
  • 对于 crops 的每个值,我们检查密钥是否已经在 op 对象中,如果它已经存在,我们根据条件更改最大值和最小值。
  • 如果不是,我们将添加一个具有适当值的新键。

var crops  = [18002, 18154, 18154, 18155, 18155, 18155, 18156, 18156, 18156, 18156, 18157, 18157, 18157, 18157, 18157, 18158, 18158, 18158, 18158, 18158, 18158, 18159, 18159, 18159, 18159, 18159, 18159, 18159, 18160, 18160, 18160, 18160, 18160, 18160, 18160, 18160, 18160, 18161, 18161, 18161, 18161, 18161, 18161, 18161, 18161, 18161, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18165, 18165, 18165, 18165, 18165, 18165, 18165, 18165, 18165, 18165, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18170, 18170, 18170, 18170, 18170, 18170, 18170, 18170, 18170, 18171, 18171, 18171, 18171, 18171, 18171, 18171, 18171, 18171, 18171, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18173, 18173, 18173, 18173, 18173, 18173, 18173, 18173, 18173, 18173, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18176, 18176, 18176, 18176, 18176];
var values = [1.69, 1.65, 1.75, 1.7, 1.7, 1.78, 1.69, 1.62, 1.75, 1.74, 1.7, 1.72, 1.68, 1.77, 1.7, 1.62, 1.74, 1.69, 1.82, 1.68, 1.64, 1.66, 1.74, 1.57, 1.7, 1.7, 1.6, 1.66, 1.72, 1.47, 1.52, 1.7, 1.63, 1.67, 1.69, 1.7, 1.51, 1.49, 1.58, 1.63, 1.66, 1.68, 1.39, 1.71, 1.61, 1.62, 1.41, 1.52, 1.46, 1.41, 1.61, 1.65, 1.36, 1.59, 1.65, 1.64, 1.72, 1.52, 1.35, 1.49, 1.65, 1.32, 1.37, 1.69, 1.62, 1.63, 1.7, 1.72, 1.7, 1.3, 1.47, 1.56, 1.5, 1.67, 1.41, 1.73, 1.71, 1.67, 1.58, 1.73, 1.56, 1.66, 1.73, 1.57, 1.69, 1.58, 1.73, 1.47, 1.7, 1.8, 1.61, 1.77, 1.79, 1.63, 1.56, 1.58, 1.59, 1.84, 1.64, 1.77, 1.63, 1.7, 1.76, 1.73, 1.83, 1.63, 1.44, 1.32, 1.74, 1.46, 1.57, 1.67, 1.4, 1.64, 1.69, 1.58, 1.76, 1.69, 1.58, 1.72, 1.43, 1.7, 1.34, 1.69, 1.64, 1.6, 1.68, 1.5, 1.69, 1.5, 1.76, 1.47, 1.7, 1.63, 1.49, 1.48, 1.15, 1.59, 1.65, 1.6, 1.46, 1.43, 1.52, 1.55, 1.63, 1.41, 1.66, 1.62, 1.66, 1.66, 1.68, 1.63, 1.66, 1.59, 1.34, 1.67, 1.68, 1.46, 1.66, 1.77, 1.71, 1.71, 1.6, 1.47, 1.71, 1.75, 1.6, 1.58, 1.35, 1.72, 1.77, 1.68, 1.64, 1.71, 1.59, 1.63, 1.74, 1.39, 1.59, 1.71, 1.72, 1.25, 1.65, 1.7, 1.67, 1.71, 1.67, 1.49, 1.69, 1.36, 1.53, 1.73, 1.57, 1.58, 1.7, 1.61, 1.61, 1.7, 1.62, 1.69];

let op = crops.reduce((op,inp,index)=>{
  let min = op[inp] && op[inp].min
  let max = op[inp] && op[inp].max
  let value = values[index]
  if(op[inp]){
    op[inp].min = value < min ? value : min
    op[inp].max = value > max ? value : max
  } else {
    op[inp] = {crop:inp,min:value,max:value}
  }
  return op
},{})

console.log(op)

我们可以将任务分为两步:
1.获取某crop对应的值
2. 获取这些值中的最小值和最大值。

对于第一步,您可以通过查看 crops 数组中的相应索引来过滤 values 数组。为此,我们获益于传递给 filter 的函数将索引作为第二个参数。 对于第二个,reduce 的替代方法是使用内置的 Math.min / Math.max 函数。

即:

var crops = [18002, 18154, 18154, 18155, 18155, 18155, 18156, 18156, 18156, 18156, 18157, 18157, 18157, 18157, 18157, 18158, 18158, 18158, 18158, 18158, 18158, 18159, 18159, 18159, 18159, 18159, 18159, 18159, 18160, 18160, 18160, 18160, 18160, 18160, 18160, 18160, 18160, 18161, 18161, 18161, 18161, 18161, 18161, 18161, 18161, 18161, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18165, 18165, 18165, 18165, 18165, 18165, 18165, 18165, 18165, 18165, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18170, 18170, 18170, 18170, 18170, 18170, 18170, 18170, 18170, 18171, 18171, 18171, 18171, 18171, 18171, 18171, 18171, 18171, 18171, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18173, 18173, 18173, 18173, 18173, 18173, 18173, 18173, 18173, 18173, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18176, 18176, 18176, 18176, 18176];
var values = [1.69, 1.65, 1.75, 1.7, 1.7, 1.78, 1.69, 1.62, 1.75, 1.74, 1.7, 1.72, 1.68, 1.77, 1.7, 1.62, 1.74, 1.69, 1.82, 1.68, 1.64, 1.66, 1.74, 1.57, 1.7, 1.7, 1.6, 1.66, 1.72, 1.47, 1.52, 1.7, 1.63, 1.67, 1.69, 1.7, 1.51, 1.49, 1.58, 1.63, 1.66, 1.68, 1.39, 1.71, 1.61, 1.62, 1.41, 1.52, 1.46, 1.41, 1.61, 1.65, 1.36, 1.59, 1.65, 1.64, 1.72, 1.52, 1.35, 1.49, 1.65, 1.32, 1.37, 1.69, 1.62, 1.63, 1.7, 1.72, 1.7, 1.3, 1.47, 1.56, 1.5, 1.67, 1.41, 1.73, 1.71, 1.67, 1.58, 1.73, 1.56, 1.66, 1.73, 1.57, 1.69, 1.58, 1.73, 1.47, 1.7, 1.8, 1.61, 1.77, 1.79, 1.63, 1.56, 1.58, 1.59, 1.84, 1.64, 1.77, 1.63, 1.7, 1.76, 1.73, 1.83, 1.63, 1.44, 1.32, 1.74, 1.46, 1.57, 1.67, 1.4, 1.64, 1.69, 1.58, 1.76, 1.69, 1.58, 1.72, 1.43, 1.7, 1.34, 1.69, 1.64, 1.6, 1.68, 1.5, 1.69, 1.5, 1.76, 1.47, 1.7, 1.63, 1.49, 1.48, 1.15, 1.59, 1.65, 1.6, 1.46, 1.43, 1.52, 1.55, 1.63, 1.41, 1.66, 1.62, 1.66, 1.66, 1.68, 1.63, 1.66, 1.59, 1.34, 1.67, 1.68, 1.46, 1.66, 1.77, 1.71, 1.71, 1.6, 1.47, 1.71, 1.75, 1.6, 1.58, 1.35, 1.72, 1.77, 1.68, 1.64, 1.71, 1.59, 1.63, 1.74, 1.39, 1.59, 1.71, 1.72, 1.25, 1.65, 1.7, 1.67, 1.71, 1.67, 1.49, 1.69, 1.36, 1.53, 1.73, 1.57, 1.58, 1.7, 1.61, 1.61, 1.7, 1.62, 1.69];

function extremeValues(crop) {
    const cropValues = values.filter((value, ix) => crops[ix] === crop)
    return {min: Math.min(...cropValues), max: Math.max(...cropValues)}
}

console.log(extremeValues(18157))

需要 "three-dot" 表示法将数组转换为可变参数计数 Math.minMath.max 函数的参数列表。

"three-dot" 的替代方法是使用 lodash 库:

const _ = require("lodash")

var crops = [18002, 18154, 18154, 18155, 18155, 18155, 18156, 18156, 18156, 18156, 18157, 18157, 18157, 18157, 18157, 18158, 18158, 18158, 18158, 18158, 18158, 18159, 18159, 18159, 18159, 18159, 18159, 18159, 18160, 18160, 18160, 18160, 18160, 18160, 18160, 18160, 18160, 18161, 18161, 18161, 18161, 18161, 18161, 18161, 18161, 18161, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18162, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18163, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18164, 18165, 18165, 18165, 18165, 18165, 18165, 18165, 18165, 18165, 18165, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18166, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18167, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18168, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18169, 18170, 18170, 18170, 18170, 18170, 18170, 18170, 18170, 18170, 18171, 18171, 18171, 18171, 18171, 18171, 18171, 18171, 18171, 18171, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18172, 18173, 18173, 18173, 18173, 18173, 18173, 18173, 18173, 18173, 18173, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18174, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18175, 18176, 18176, 18176, 18176, 18176];
var values = [1.69, 1.65, 1.75, 1.7, 1.7, 1.78, 1.69, 1.62, 1.75, 1.74, 1.7, 1.72, 1.68, 1.77, 1.7, 1.62, 1.74, 1.69, 1.82, 1.68, 1.64, 1.66, 1.74, 1.57, 1.7, 1.7, 1.6, 1.66, 1.72, 1.47, 1.52, 1.7, 1.63, 1.67, 1.69, 1.7, 1.51, 1.49, 1.58, 1.63, 1.66, 1.68, 1.39, 1.71, 1.61, 1.62, 1.41, 1.52, 1.46, 1.41, 1.61, 1.65, 1.36, 1.59, 1.65, 1.64, 1.72, 1.52, 1.35, 1.49, 1.65, 1.32, 1.37, 1.69, 1.62, 1.63, 1.7, 1.72, 1.7, 1.3, 1.47, 1.56, 1.5, 1.67, 1.41, 1.73, 1.71, 1.67, 1.58, 1.73, 1.56, 1.66, 1.73, 1.57, 1.69, 1.58, 1.73, 1.47, 1.7, 1.8, 1.61, 1.77, 1.79, 1.63, 1.56, 1.58, 1.59, 1.84, 1.64, 1.77, 1.63, 1.7, 1.76, 1.73, 1.83, 1.63, 1.44, 1.32, 1.74, 1.46, 1.57, 1.67, 1.4, 1.64, 1.69, 1.58, 1.76, 1.69, 1.58, 1.72, 1.43, 1.7, 1.34, 1.69, 1.64, 1.6, 1.68, 1.5, 1.69, 1.5, 1.76, 1.47, 1.7, 1.63, 1.49, 1.48, 1.15, 1.59, 1.65, 1.6, 1.46, 1.43, 1.52, 1.55, 1.63, 1.41, 1.66, 1.62, 1.66, 1.66, 1.68, 1.63, 1.66, 1.59, 1.34, 1.67, 1.68, 1.46, 1.66, 1.77, 1.71, 1.71, 1.6, 1.47, 1.71, 1.75, 1.6, 1.58, 1.35, 1.72, 1.77, 1.68, 1.64, 1.71, 1.59, 1.63, 1.74, 1.39, 1.59, 1.71, 1.72, 1.25, 1.65, 1.7, 1.67, 1.71, 1.67, 1.49, 1.69, 1.36, 1.53, 1.73, 1.57, 1.58, 1.7, 1.61, 1.61, 1.7, 1.62, 1.69];

function extremeValues(crop) {
    const cropValues = values.filter((value, ix) => crops[ix] === crop)
    return {min: _.min(cropValues), max: _.max(cropValues)}
}

当然,您需要合并 lodash 库才能使后一个选项起作用。

希望对您有所帮助 - 卡洛斯