So you want to take an array that looks like this:
const hits = [
{ name: 'Tammy', class: 'Class 1' },
{ name: 'Sarah', class: 'Class 2' },
{ name: 'Roland', class: 'Class 3' },
{ name: 'Moshe', class: 'Class 4' },
{ name: 'Peter', class: 'Class 5' },
];
And transform it into an array of names, arranged into columns by their classname, like this:
const rows = [
['Tammy', 'Sarah', 'Roland', 'Moshe', 'Peter'],
['Helen', 'Eric', 'Fiona', 'Darren', 'Andy'],
];
Thats going to take a bit of work. I don’t think that you will be able to accomplish it with if/else statement inside a few map functions.
Let’s try this. I propose adding a class method to your component called getRows. This method will do the transformation. We start by iterating over your hits
and grouping the names by class.
Then we setup a while loop, to push the names into the new rows array. While we still have names, keep building rows. Each row will pick a name according to the column and insert it.
Finally, when we are all out of names, we can return the rows to the render function. Then we map the rows, and map the columns in each rows. We also need unique keys for each mapped element.
getRows()
const getRows = () => {
const columns = ['Class 1', 'Class 2', 'Class 3', 'Class 4', 'Class 5'];
const rows = [];
const groupByColumn = this.state.hits.reduce((acc, next) => {
return { ...acc, [next.class]: [...(acc[next.class] || []), next.name] };
}, {});
const haveNames = () => columns.some((column) => (groupByColumn[column] || []).length > 0);
while (haveNames()) {
const newRow = columns.map((column) => {
return (groupByColumn[column] || []).shift() || '';
});
rows.push(newRow);
}
return rows;
};
The complete component:
import React, { Component } from 'react';
class App extends Component {
constructor(props) {
super(props);
this.state = {
hits: [],
isLoading: false,
error: null,
};
}
async componentDidMount() {
this.setState({ isLoading: true });
const response = await fetch('https://xxxxxxx');
const body = await response.json();
this.setState({ hits: body, isLoading: false, error: null });
}
getRows = () => {
const columns = ['Class 1', 'Class 2', 'Class 3', 'Class 4', 'Class 5'];
const rows = [];
const groupByColumn = this.state.hits.reduce((acc, next) => {
return { ...acc, [next.class]: [...(acc[next.class] || []), next.name] };
}, {});
const haveNames = () => columns.some((column) => (groupByColumn[column] || []).length > 0);
while (haveNames()) {
const newRow = columns.map((column) => {
return (groupByColumn[column] || []).shift() || '';
});
rows.push(newRow);
}
return rows;
};
render() {
if (this.state.error) {
return <p>{error.message}</p>;
}
if (this.state.isLoading) {
return <p>Loading ...</p>;
}
return (
<form>
<div className="container border border-secondary rounded center">
<div className="row">
<div className="col-12">
{' '}
<h4>
<b>Class Mapping</b>
</h4>{' '}
</div>
</div>
<div className=".col-xs-12 center text-center">
<Table responsive striped bordered hover>
<tr>
<th>Class 1</th>
<th>Class 2</th>
<th>Class 3</th>
<th>Class 4</th>
<th>Class 5</th>
</tr>
<tbody>
{this.getRows().map((row) => (
<tr key={row.reduce((a, b) => a + b)}>
{row.map((column) => (
<td key={column}>{column}</td>
))}
</tr>
))}
</tbody>
</Table>
</div>
</div>
</form>
);
}
}
export default App;
Example code
const hits = [
{ name: 'Tammy', class: 'Class 1' },
{ name: 'Camen', class: 'Class 2' },
{ name: 'Happy', class: 'Class 3' },
{ name: 'Hello Kitty', class: 'Class 4' },
{ name: 'Hello Mimi', class: 'Class 3' },
];
const getRows = (hits) => {
const columns = ['Class 1', 'Class 2', 'Class 3', 'Class 4', 'Class 5'];
const rows = [];
const groupByColumn = hits.reduce((acc, next) => {
return { ...acc, [next.class]: [...(acc[next.class] || []), next.name] };
}, {});
const haveNames = () => columns.some((column) => (groupByColumn[column] || []).length > 0);
while (haveNames()) {
const newRow = columns.map((column) => {
return (groupByColumn[column] || []).shift() || '';
});
rows.push(newRow);
}
return rows;
};
const rows = getRows(hits);
console.log(rows);
CLICK HERE to find out more related problems solutions.