在减少功能的javascript中找到最大值和最小值

时间:2019-09-03 06:53:07

标签: javascript arrays object reduce

如何在reduce函数中找到最大值和最小值。我可以在数据集中进行'a'和'b'的求和,但是我找不到最大值a和最小值b并将其添加到相同的列表

var liste = [
  {"id":1,"a":5,"b":4},
  {"id":1,"a":2,"b":2},
  {"id":1,"a":7,"b":1},
  {"id":1,"a":1,"b":0},
  
  {"id":2,"a":11,"b":5},
  {"id":2,"a":32,"b":75},
  {"id":3,"a":1,"b":1},
  {"id":4,"a":1,"b":1},
  {"id":4,"a":213,"b":1},
  {"id":5,"a":1,"b":1},
  {"id":5,"a":1,"b":1},
]
var max = 0;
let map = liste.reduce((prev, next) => {  
  
    if (next.id in prev) {
       prev[next.id].a += next.a;
       prev[next.id].b += next.b;
       if(next.a > max){
         max = next.a;
         prev[next.id].max = max;
         
       }
    } else {
       prev[next.id] = next;
      
       next.max =max
    }
    return prev;
}, {});
let result = Object.keys(map).map(id => map[id]);
console.log(result);

2 个答案:

答案 0 :(得分:1)

您基本上就是在做您要做的事情,只是在进行汇总的条目中包括ab的最大值。

但是reduce是错误的工具,您需要的只是一个简单的for-of循环。 (您可以 将其刺入reduce调用,因为基本上任何数组操作都可以被刺入reduce调用,但是除了复杂性之外,它不会给您带来任何好处。)我还会使用Map而不是空白对象进行查找(但是对象也可以工作;为此使用对象时,我通常建议通过Object.create(null)创建没有原型的对象)。

const map = new Map();
for (const entry of liste) {
    const {id, a, b} = entry;
    // Do we have an entry for this ID?
    let known = map.get(id);
    if (!known) {
        // No, use this one (note: I would make a copy rather than modifying the original)
        known = entry;
        map.set(id, entry);
        // Initialize its max with the values from this entry
        entry.max_a = a;
        entry.max_b = b;
    } else {
        // Update our max values
        known.max_a = Math.max(known.max_a, a);
        known.max_b = Math.max(known.max_b, b);
        // Add in the current entries to the sum
        known.a += a;
        known.b += b;
    }
}
// Show the result
console.log([...map.values()]);

实时示例:

var liste = [
  {"id":1,"a":5,"b":4},
  {"id":1,"a":2,"b":2},
  {"id":1,"a":7,"b":1},
  {"id":1,"a":1,"b":0},
  
  {"id":2,"a":11,"b":5},
  {"id":2,"a":32,"b":75},
  {"id":3,"a":1,"b":1},
  {"id":4,"a":1,"b":1},
  {"id":4,"a":213,"b":1},
  {"id":5,"a":1,"b":1},
  {"id":5,"a":1,"b":1},
]
const map = new Map();
for (const entry of liste) {
    const {id, a, b} = entry;
    // Do we have an entry for this ID?
    let known = map.get(id);
    if (!known) {
        // No, use this one (note: I would make a copy rather than modifying the original)
        known = entry;
        map.set(id, entry);
        // Initialize its max with the values from this entry
        entry.max_a = a;
        entry.max_b = b;
    } else {
        // Update our max values
        known.max_a = Math.max(known.max_a, a);
        known.max_b = Math.max(known.max_b, b);
        // Add in the current entries to the sum
        known.a += a;
        known.b += b;
    }
}
// Show the result
console.log([...map.values()]);
.as-console-wrapper {
    max-height: 100% !important;
}

答案 1 :(得分:0)

您可以检查id是否存在并更新对象,否则用给定值以及最小值和最大值创建一个新对象。

var liste = [{ id: 1, a: 5, b: 4 }, { id: 1, a: 2, b: 2 }, { id: 1, a: 7, b: 1 }, { id: 1, a: 1, b: 0 }, { id: 2, a: 11, b: 5 }, { id: 2, a: 32, b: 75 }, { id: 3, a: 1, b: 1 }, { id: 4, a: 1, b: 1 }, { id: 4, a: 213, b: 1 }, { id: 5, a: 1, b: 1 }, { id: 5, a: 1, b: 1 }],
    global_min = Infinity,
    global_max = -Infinity,
    map = liste.reduce((r, { id, a, b }) => {
        if (id in r) {
            r[id].a += a;
            r[id].b += b;
            r[id].max = Math.max(r[id].max, a);
            r[id].min = Math.min(r[id].min, b);
        } else {
            r[id] = { id, a, b, max: a, min: b };
        }
        global_max = Math.max(global_max, a);
        global_min = Math.min(global_min, b);
        return r;
    }, {}),
    result = Object.values(map).map(o => Object.assign(o, { global_max, global_min }));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }