Reduce JavaScrip Array of Objects based on boolean property value

I’m trying to reduce the following data from video info into a custom Object structure that removes "label" keys duplicates but also keeps true all the encountered features that are available.

The initial data looks like this:

[
  {
    "label": "4320p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "2160p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "2160p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "1440p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "1440p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "1080p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "1080p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "1080p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "1080p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "720p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "720p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "720p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "720p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "720p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "720p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "480p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "480p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "480p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "480p",
    "features": {
      "HDR": true,
      "60fps": false
    }
  },
  {
    "label": "360p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "360p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "360p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "360p",
    "features": {
      "HDR": true,
      "60fps": false
    }
  },
  {
    "label": "240p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "240p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "240p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "240p",
    "features": {
      "HDR": true,
      "60fps": false
    }
  },
  {
    "label": "144p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "144p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "144p",
    "features": {
      "HDR": false,
      "60fps": false
    }
  },
  {
    "label": "144p",
    "features": {
      "HDR": true,
      "60fps": false
    }
  }
]

As you can see there are many Objects for a single resolution label but some of them have HDR while others have 60fps while other might have none of them or just both.

What I’m trying to do is to reduce this array with the following reduce function.
Assuming that resolutions is the above Object:

resolutions.reduce((unique, o) => {
    if (!unique.some((obj) => obj.label === o.label)) {
      unique.push(o);
    }
    return unique;
  }, []);

That gives me the following structure:

[
  {
    "label": "4320p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "2160p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "1440p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "1080p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "720p",
    "features": {
      "HDR": false,
      "60fps": true
    }
  },
  {
    "label": "480p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "360p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "240p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  },
  {
    "label": "144p",
    "features": {
      "HDR": true,
      "60fps": true
    }
  }
]

But if you look closer you’ll see that during the reduce operation some booleans are merged with the first element value for each unique label key and I need to have in the end the true feature enabled even if just one of them was true.
The 2160p label is a good example where there actually is an object that has HDR: true but in the end I just get it as false

Do you have any idea on how to manage this situation with modern JavaScript?

35 thoughts on “Reduce JavaScrip Array of Objects based on boolean property value”

Leave a Comment