4

I am working on ReactJS and was wondering if there is a way to convert a javascript array from row into column.

[
    { study: 'KOOS', date: '05/06/2005', question: 'Standing upright', answer: 'Moderate' },
    { study: 'KOOS', date: '05/06/2006', question: 'Standing upright', answer: 'Severe' },
    { study: 'KOOS', date: '05/06/2007', question: 'Standing upright', answer: 'Extreme' },
    { study: 'KOOS', date: '05/06/2008', question: 'Standing upright', answer: 'Severe' },
    { study: 'KOOS', date: '05/06/2005', question: 'Going up or down stairs', answer: 'Extreme' },
    { study: 'KOOS', date: '05/06/2006', question: 'Going up or down stairs', answer: 'Moderate' },
    { study: 'KOOS', date: '05/06/2007', question: 'Going up or down stairs', answer: 'Extreme' },
    { study: 'KOOS', date: '05/06/2008', question: 'Going up or down stairs', answer: 'Moderate' }
]

I want to convert this into data an html table/div like this:

Study: Koos
Question                | 05/06/2005 | 05/06/2006 | 05/06/2007 | 05/06/2008 
Standing upright        | Moderate   | Severe     | Extreme    | Severe
Going up or down stairs | Extreme    | Moderate   | Extreme    | Moderate

I found this excellent library - json-to-pivot-json. This is something that I wanted to use, but only issue is that aggregates the value.

I see lot of examples in sql but couldn't find anything similar for javascript.

To help others, I am adding the complete JSX code to display the result as suggested by Rafael.

var output = coll2tbl(surveyResult, "question", "date", "answer"); 

const mappedCells = output.cells.map((row, index) => {
    row.unshift(output.row_headers[index]);
    return row;
})

<table>
    <thead>
        <th>Question</th>
        {
            output.col_headers.map(c => {
                return (
                    <th>{c}</th>
                );
            })                                    
        }   
    </thead>
    <tbody>
    {
        mappedCells.map(row => (
            <tr>{ row.map(cell => (<td>{cell}</td>))}</tr>
        ))
    }                   
    </tbody>
</table>
1
  • if you need to aggregate the existing array of object then build a new object out of it. Commented Oct 12, 2017 at 2:08

1 Answer 1

2

Collection to Table-Ready Data-Structure

Pass the collection and the appropriate property descriptors to the coll2tbl function and it will output a table-ready data-structure:

var data = [
    { study: 'KOOS', date: '05/06/2005', question: 'Standing upright', answer: 'Moderate' },
    { study: 'KOOS', date: '05/06/2006', question: 'Standing upright', answer: 'Severe' },
    { study: 'KOOS', date: '05/06/2007', question: 'Standing upright', answer: 'Extreme' },
    { study: 'KOOS', date: '05/06/2008', question: 'Standing upright', answer: 'Severe' },
    { study: 'KOOS', date: '05/06/2005', question: 'Going up or down stairs', answer: 'Extreme' },
    { study: 'KOOS', date: '05/06/2006', question: 'Going up or down stairs', answer: 'Moderate' },
    { study: 'KOOS', date: '05/06/2007', question: 'Going up or down stairs', answer: 'Extreme' },
    { study: 'KOOS', date: '05/06/2008', question: 'Going up or down stairs', answer: 'Moderate' }
];

function get_prop(obj, prop) {
    return prop.split('.').reduce((o,k) => obj[k], obj);
}

function coll2tbl(coll, row_header, col_header, cell) {
    var table = {};
    var row_headers = [];
    var cols = {};

    coll.forEach(a => {
        var h = get_prop(a, row_header);
        if (h in table === false) {
            table[h] = {};
            row_headers.push(h);
        }
        var c = get_prop(a, col_header);
        cols[c] = null;
        table[h][c] = get_prop(a, cell);
    });

    var cells = [];
    for (var row in table)
        cells.push(Object.values(table[row]));

    return { row_headers, col_headers: Object.keys(cols), cells };
}

var table = coll2tbl(data, 'question', 'date', 'answer');
console.log(table);

Output:

{ row_headers: [ 'Standing upright', 'Going up or down stairs' ],
  col_headers: [ '05/06/2005', '05/06/2006', '05/06/2007', '05/06/2008' ],
  cells: 
   [ [ 'Moderate', 'Severe', 'Extreme', 'Severe' ],
     [ 'Extreme', 'Moderate', 'Extreme', 'Moderate' ] ] }

Making the thead

  1. add a static th to the beginning of the thead, this is where your Question string will go.
  2. add a th per ch in col_headers

Making the tbody

  1. iterate the cells returned by coll2tbl().
    1. every parent iteration, make a new tr.
    2. add the row header cell by using the parent iterator's counter to grab the corresponding row header (table.row_headers[i]).
    3. The inner loop will create the cells, td, (table.cells[i][j]).

Ideally, you would make a react component that takes this data-structure and creates the html for you.

Sign up to request clarification or add additional context in comments.

1 Comment

I have posted a question for a bug in your solution. stackoverflow.com/questions/52197974/convert-json-data-to-table

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.