How to convert nested array to Table Javascript React

Viewed 103

I have a nested array, and want to convert it into a table in React.

For example, my data is represented as:

data = [[a,b,c], [d,e,f], [g, h, i]]

and I would like to represent it as a table in React that looks something like:

a d g

b e h

c f i

with each entry in the data list as a column, and the first entry in each nested list (a, d, and g in my case) as headers. I have been trying to use nested map functions, but have been unsuccessful

2 Answers

Array.map() is your new best friend!

First though, it is much easier to do rows first, then columns, so you'll want to reformat your data from

[[a,b,c], [d,e,f], [g, h, i]]

to

[[a,d,g], [b,e,h], [c,f,i]]

After you've done this, you can use map() to iterate over each child array. Each child array will be its own <tr />. Inside of the <tr /> you can iterate over each element in the child array, placing each inside of a <td />.

The result might look something like this

// The data
const data = [[a,d,g], [b,e,h], [c,f,i]]

// Inside the component
<table>
    {
        data.map((row, index) => {
            return (
                <tr key={index}>
                    {
                        row.map((cell, index) => {
                            return <td key={index}>{cell}</td>
                        })
                    }
                </tr>
            )
        })
    }
</table>

Hopefully this helps!

You need a combination of reduce and map:

const datas = [["a","b","c"], ["d","e","f"], ["g", "h", "i"]];

const rows = datas.reduce((acc, data,i) => {
    // pick first data as key that going to be the header
    const key = data.shift();

    // map the rest to define the row object
    const row = data.map((val, n) => {
        // add key to the existing row object
        if (i > 0) {
            acc[n][key] = val;
            return acc[n];
        }
        // create new row object
        return { [key]: val };
    });
    // return row as accumulator
    return row
},[])

console.log(rows)

Here the implementation on react-table v7

const { useCallback, useEffect, useMemo, useState } = React;
const { useTable } = ReactTable;

const tableData = [["a","b","c"], ["d","e","f"], ["g", "h", "i"]];

function App() {
    const columns = useMemo(() => [
        {
            Header: 'Column A',
            accessor: 'a',
        },
        {
            Header: 'Column D',
            accessor: 'd',
        },
        {
            Header: 'Column G',
            accessor: 'g',
        },
    ],[]);

    const data = useMemo(() => {
        return tableData.reduce((acc, data,i) => {
            const key = data.shift();
            const row = data.map((val, n) => {
                if (i > 0) {
                    acc[n][key] = val;
                    return acc[n];
                }
                return { [key]: val };
            });
            return row
        },[])
    },[]);
    
    const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        rows,
        prepareRow
    } = useTable({
        columns,
        data
    });

    return (
        <div>
            <table {...getTableProps()}>
                <thead>
                    {headerGroups.map(headerGroup => (
                        <tr {...headerGroup.getHeaderGroupProps()}>
                            {headerGroup.headers.map(column => (
                                <th {...column.getHeaderProps()}> 
                                    {column.render('Header')}
                                </th>
                            ))}
                    </tr>
                    ))}
                </thead>
                <tbody {...getTableBodyProps()}>
                    {rows.map((row, i) => {
                        prepareRow(row)
                        return (
                            <tr {...row.getRowProps()}>
                                {row.cells.map(cell => {
                                    return (
                                        <td {...cell.getCellProps()}> 
                                            {cell.render('Cell')}
                                        </td>
                                    )
                                })}
                            </tr>
                        )
                    })}
                </tbody>
            </table>
        </div>
    )
   
}
 
ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/react-table@7.8.0/dist/react-table.development.js"></script>

<div class='react'></div>

Related