8

I have object that looks like this:

peaks = 
0: {intervalId: 7, time: 1520290800000, value: 54.95125000000001}
1: {intervalId: 7, time: 1520377200000, value: 49.01083333333333}

and so on.

How do I find peak that has Max value? I tried to do it like this

this.loadPeak = peaks.map(a => Math.max(a.value));

but I just got bunch of peaks array with value (instead of all intervalId, time, value) and not the max value.

**Thank you so much for everyone, every solution was working, sadly can't accept all. **

user122222
  • 2,179
  • 4
  • 35
  • 78
  • @Christian - The OP here seems to want to find the *object* with the max value, rather than the max value. (I read it that way at first, too.) But I bet there's a dupetarget for that, too... :-) – T.J. Crowder Oct 21 '18 at 15:09

4 Answers4

12

The main issue with sorting your array, is it causes many needless iterations through your array. This gets drastically slower the bigger your array is, sorting to try and move elements up and down. With reduce(), we can handle this in the minimum amount of steps needed, simply replacing the previous value if the current element's value is greater than the previous:

var peaks = [
  {intervalId: 7, time: 1520290800000, value: 54.95125000000001},
  {intervalId: 7, time: 1520377200000, value: 49.01083333333333}
];

const maxPeak = peaks.reduce((p, c) => p.value > c.value ? p : c);

console.log(maxPeak);
Blue
  • 22,608
  • 7
  • 62
  • 92
6

You could spread only the value value for Math.max.

var peaks = [{ intervalId: 7, time: 1520290800000, value: 54.95125000000001 }, { intervalId: 7, time: 1520377200000, value: 49.01083333333333 }]
    max = Math.max(...peaks.map(({ value }) => value)),
    object = peaks.find(({ value }) => value === max);

console.log(max);
console.log(object);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
2

The simple way is just to use a loop:

this.loadPeak = null;
for (const peak of peaks) {
    if (!this.loadPeak || peak.value > this.loadPeak.value) {
        this.loadPeak = peak;
    }
}

Live Example:

const peaks = [
  {intervalId: 7, time: 1520290800000, value: 54.95125000000001},
  {intervalId: 7, time: 1520377200000, value: 49.01083333333333}
];

let loadPeak = null;
for (const peak of peaks) {
    if (!loadPeak || peak.value > loadPeak.value) {
        loadPeak = peak;
    }
}
console.log(loadPeak);

As with nearly any array operation, you can shoe-horn it into a reduce call if you like:

this.loadPeak = peaks.reduce((maxPeak, peak) => !maxPeak || maxPeak.value < peak.value ? peak : maxPeak, null);

const peaks = [
  {intervalId: 7, time: 1520290800000, value: 54.95125000000001},
  {intervalId: 7, time: 1520377200000, value: 49.01083333333333}
];

const loadPeak = peaks.reduce((maxPeak, peak) => !maxPeak || maxPeak.value < peak.value ? peak : maxPeak, null);
console.log(loadPeak);

I should have realized earlier this was a duplicate question. I've found the dupetarget, marked it, and made this a CW answer.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

You can sort your peaks in descending order of value, then pick the first of the sorted array.

let peaks = [{
    intervalId: 7,
    time: 1520290800000,
    value: 54.95125000000001
  },
  {
    intervalId: 7,
    time: 1520377200000,
    value: 49.01083333333333
  }
]

let sortedPeaks = peaks.sort((a, b) => b.value - a.value)

let loadPeak = sortedPeaks[0];

console.log(loadPeak);
Ayush Gupta
  • 8,716
  • 8
  • 59
  • 92