React

HTML

<div id="app"></div>

CSS

body {
  font-family: sans-serif;
  margin: 0;
  background: #ccc;
}

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 20px;
  margin: 20px;
}

.dataOutput,
.uiOutput,
.group,
.item {
  background: #fff;
  box-shadow: 0 0 20px rgba(0,0,0,0.2);
  padding: 10px;
  border: 2px solid;
}

.dataOutput {
  display: flex;
  flex-direction: column;
}

.one {
  border-color: blue;
}

.two {
  border-color: green;
}

.three {
  border-color: red;
}

header {
  margin-bottom: 10px;
}

h2,
h3,
strong {
  font-weight: bold;
}

span {
  font-size: 14px;
  color: #666;
}

pre {
  background: #21262d;
  color: #bec3cc;
  padding: 10px;
  flex: 1;
}

.uiOutput {
  margin: 20px;
  border-color: #000;
}

.group,
.item {
  border: 1px solid #aaa;
  margin: 20px;
}

.group + .group {
  margin-top: 40px;
}

React

class App extends React.Component {
  render() {
  	// Data format that I'm starting with:
    // It's pre-sorted
  	const originalData = [
      {
        groupId: 0,
        color: "red",
        shape: "circle"
      },
      {
        groupId: 1,
        color: "green",
        shape: "square"
      },
      {
        groupId: 1,
        color: "orange",
        shape: "hexagon"
      },
      {
        groupId: 1,
        color: "purple",
        shape: "triangle"
      },
      {
        groupId: 2,
        color: "aqua",
        shape: "diamond"
      },
      {
        groupId: 2,
        color: "blue",
        shape: "trapezoid"
      }
    ];

    // Data format that I want to end up wit:h
    const desiredData = [
      {
        groupId: 0,
        items: [
          {
            color: "red",
            shape: "circle"
          }
        ]
      },
      {
        groupId: 1,
        items: [
          {
            color: "green",
            shape: "square"
          },
          {
            color: "orange",
            shape: "hexagon"
          },
          {
            color: "purple",
            shape: "triangle"
          }
        ]
      },
      {
        groupId: 2,
        items: [
          {
            color: "aqua",
            shape: "diamond"
          },
          {
            color: "blue",
            shape: "trapezoid"
          }
        ]
      }
    ];

		// Data format that I'm currently getting:
    // This function is based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#Grouping_objects_by_a_property
		const actualFormattedData = originalData.reduce((acc, obj) => {
      let key = obj['groupId'];
      if (!acc[key]) {
        acc[key] = [];
      }
      acc[key].push(obj);
      return acc;
    }, {});

		// Function to pretty print data
		const printData = (data) => {
    	return (
      	<pre>
          <code>
            {JSON.stringify(data, null, 2)}
        ...