John John
John John

Reputation: 1455

How to find more than one highest size using reduce() JavaScript

I am trying to find the highest size accSixe = acc.width * acc.height which is not a problem. The trick is if there is more than one highest size how would i get it - really important- using reduce(). I am trying to understand the ins and outs of reduce() . Any one to help?

    const boxarts = [
    { width: 200, height: 200, url: "http://cdn-0.nflximg.com/images/2891/Fracture200.jpg" },
    { width: 300, height: 200, url: "http://cdn-0.nflximg.com/images/2891/Fracture300.jpg" },
    { width: 400, height: 200, url: "http://cdn-0.nflximg.com/images/2891/Fracture400.jpg" },
    { width: 500, height: 200, url: "http://cdn-0.nflximg.com/images/2891/Fracture500.jpg" },
    { width: 150, height: 200, url: "http://cdn-0.nflximg.com/images/2891/Fracture150.jpg" },
    { width: 600, height: 200, url: "http://cdn-0.nflximg.com/images/2891/Fracture600-.jpg" },
    { width: 600, height: 200, url: "http://cdn-0.nflximg.com/images/2891/Fracture600+.jpg" },
    { width: 600, height: 200, url: "http://cdn-0.nflximg.com/images/2891/Fracture600.jpg" },
    { width: 425, height: 150, url: "http://cdn-0.nflximg.com/images/2891/Fracture425.jpg" }
]

        const newReduce = boxarts.reduce(function (acc, currentValue) {

            const accSixe = acc.width * acc.height
            const curSize = currentValue.width * currentValue.height

            if (accSixe > curSize) {
                return acc
            } else {
                return currentValue
            }
        }, [])


        console.log(JSON.stringify(newReduce, null, 2))

Upvotes: 0

Views: 49

Answers (2)

Steve Bennett
Steve Bennett

Reputation: 126045

IMHO this problem isn't well suited to using .reduce(). You could solve it very straightforwardly simply iterating over item and storing the current largest items in an array.

 let maxSize = 0;
 let biggest = [];
 boxarts.forEach(function(box) {
    if (box.width * box.height > maxSize) {
      maxSize = box.width * box.height;
      biggest = [box];
    } else if (box.width * box.height === maxSize) {
      biggest.push(box);
    }
 });

Super straightforward to read and reason about.

Upvotes: 0

CertainPerformance
CertainPerformance

Reputation: 370649

Have the accumulator be an object of an array and the current highest value:

const boxarts=[{width:200,height:200,url:"http://cdn-0.nflximg.com/images/2891/Fracture200.jpg"},{width:300,height:200,url:"http://cdn-0.nflximg.com/images/2891/Fracture300.jpg"},{width:400,height:200,url:"http://cdn-0.nflximg.com/images/2891/Fracture400.jpg"},{width:500,height:200,url:"http://cdn-0.nflximg.com/images/2891/Fracture500.jpg"},{width:150,height:200,url:"http://cdn-0.nflximg.com/images/2891/Fracture150.jpg"},{width:600,height:200,url:"http://cdn-0.nflximg.com/images/2891/Fracture600-.jpg"},{width:600,height:200,url:"http://cdn-0.nflximg.com/images/2891/Fracture600+.jpg"},{width:600,height:200,url:"http://cdn-0.nflximg.com/images/2891/Fracture600.jpg"},{width:425,height:150,url:"http://cdn-0.nflximg.com/images/2891/Fracture425.jpg"}]

const { arr } = boxarts.reduce(({ highest = 0, arr = [] }, boxart) => {
  const { width, height } = boxart;
  const thisSize = width * height;
  if (thisSize > highest) return { highest: thisSize, arr: [boxart] };
  if (thisSize === highest) arr.push(boxart);
  return { highest, arr };
}, {});
console.log(arr);

Another option would be for the accumulator be the array itself, but you'd have to extract and multiply the record width * height every iteration:

const boxarts=[{width:200,height:200,url:"http://cdn-0.nflximg.com/images/2891/Fracture200.jpg"},{width:300,height:200,url:"http://cdn-0.nflximg.com/images/2891/Fracture300.jpg"},{width:400,height:200,url:"http://cdn-0.nflximg.com/images/2891/Fracture400.jpg"},{width:500,height:200,url:"http://cdn-0.nflximg.com/images/2891/Fracture500.jpg"},{width:150,height:200,url:"http://cdn-0.nflximg.com/images/2891/Fracture150.jpg"},{width:600,height:200,url:"http://cdn-0.nflximg.com/images/2891/Fracture600-.jpg"},{width:600,height:200,url:"http://cdn-0.nflximg.com/images/2891/Fracture600+.jpg"},{width:600,height:200,url:"http://cdn-0.nflximg.com/images/2891/Fracture600.jpg"},{width:425,height:150,url:"http://cdn-0.nflximg.com/images/2891/Fracture425.jpg"}]

const arr = boxarts.reduce((foundSoFar, boxart) => {
  const record = foundSoFar[0].width * foundSoFar[0].height;
  const { width, height } = boxart;
  const thisSize = width * height;
  if (thisSize > record) return [boxart]
  if (thisSize === record) foundSoFar.push(boxart);
  return foundSoFar;
}, [{ width: 0, height: 0 }]);
console.log(arr);

Upvotes: 2

Related Questions