davren
davren

Reputation: 23

Creating table from arrays Javascript

I’m looking to get a set of arrays and transform them into a table object (or something table-like). In this case, I have a list of potential RGB values.
I'm not concerned about visualizing the 2 dimensional object, but just selecting and manipulating from it.

Here's what I start with: a group of arrays:

["Class", "R", "G", "B"],
["1", "166", "206", "227"],
["2", "31", "120", "180"], 
["3", "51", "160", "44"]

I then want to be able to select things based on either column or row. I'm more concerned with ease of selecting elements rather than creating html objects (tr/td). I want to select and process data based on column identifier (R: "166","31", "51" -- for example), or by row identifier (1: "31", "120", "180" --- for example).

Class   |   R    |    G    |    B  
1       |  166   |   206   |   227  
2       |   31   |   120   |   180   
3       |   51   |   160   |    44  

Here are my questions:
1. What kind of object am I looking for?
2. How would I create it from a series of arrays, where the key/table header is based on the first array (dynamic assignment - rather than hard coded)?

I appreciate your thoughts on this:

David

Upvotes: 2

Views: 109

Answers (2)

spiker830
spiker830

Reputation: 16

Here's what I came up with. Benefit being that it is a reusable data structure independent of what the columns names are and you can keep your original data structure (array of arrays). You'll want to add any necessary sanity checks where necessary (making sure rows/columns exist, etc).

https://jsfiddle.net/z129o3v9/4/

var RGBData = function(arrayOfDataElements) {

    this.keys = arrayOfDataElements[0];
    this.data = arrayOfDataElements.slice(1);

    this.getRow = function(row) {
        return this.data[row-1].slice(1);
    };

    this.getColumn = function(column) {
        return this.data.map(function(row) {
            return row[this.keys.indexOf(column)];
        }, this);
    };

    this.addRow = function(row) {
        this.data.push(row);
    }

    this.updateValue = function(row, column, value) {
        var index = this.keys.indexOf(column);
        this.data[row-1][index] = value;
    };
};

var arrayOfDataElements = [
    ["Class", "R", "G", "B"],
    ["1", "166", "206", "227"],
    ["2", "31", "120", "180"]
];

var data = new RGBData(arrayOfDataElements);

alert("Row 2: " + data.getRow("2"));
alert("Column R: " + data.getColumn("R"));
data.updateValue("2", "R", "69");
alert("Column R after update: " + data.getColumn("R"));

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386560

I suggest an array with objects:

var color = [
    { Class: 1, R: 166, G: 206, B: 227 },
    { Class: 2, R: 31, G: 120, B: 180 },
    { Class: 3, R: 51, G: 160, B: 44 }
];

and

var classIndex = {
    '1': 0,
    '2': 1,
    '3': 2
};

for the storage of the index of the array items.

Access via color[classIndex[1]]['R']

Working example:

function colorType(cl, r, g, b) {
    return { Class: cl, R: r, G: g, B: b };
}

function addColor(ct) {
    color.push(ct);
    classIndex = {};
    color.forEach(function (a, i) { classIndex[a.Class] = i; });
}

function getColorColumn(key) {
    return color.map(function (a) { return a[key]; });
}

function updateColorColumn(key, values) {
    color.forEach(function (a, i) { a[key] = values[i]; });
}

function changeColumn(key, cb) {
    color.forEach(function (a, i) { a[key] = cb(a[key]); });
}

var color = [
        { Class: 1, R: 166, G: 206, B: 227 },
        { Class: 2, R: 31, G: 120, B: 180 },
        { Class: 3, R: 51, G: 160, B: 44 }
    ],
    classIndex = {
        '1': 0,
        '2': 1,
        '3': 2
    };

// display a single item
document.write('<pre>color[classIndex[1]][\'R\']: ' + color[classIndex[1]]['R'] + '</pre>');

// display the color array
document.write('<pre>color: ' + JSON.stringify(color, 0, 4) + '</pre>');

// add a new color
addColor(colorType(4, 51, 102, 153));
document.write('<pre>color after insert: ' + JSON.stringify(color, 0, 4) + '</pre>');
document.write('<pre>classIndex after insert: ' + JSON.stringify(classIndex, 0, 4) + '</pre>');

// get column B
var blue = getColorColumn('B');
document.write('<pre>blue: ' + JSON.stringify(blue, 0, 4) + '</pre>');

// change blue
blue = blue.map(function (a) { return Math.min(a * 1.2, 255) | 0; });
document.write('<pre>blue after update: ' + JSON.stringify(blue, 0, 4) + '</pre>');

// update column B with blue
updateColorColumn('B', blue);
document.write('<pre>color after changing B: ' + JSON.stringify(color, 0, 4) + '</pre>');

// change R directly
changeColumn('R', function (v) { return Math.max(v * 0.5, 0) | 0; });
document.write('<pre>color after changing R: ' + JSON.stringify(color, 0, 4) + '</pre>');

Upvotes: 1

Related Questions