Reduce time complexity in formatting loop

I am writing a component in Vue that lets us take an array of objects for a table and apply HTML formatting to the data, but the way I have it written currently is an O(n^2) complexity, and I am not sure how to make it any faster.

example row data:

[
    {
        "product": "Socks",
        "price": 39,
        "sales": 20,
        "inventory": 68
    },
    {
        "product": "Shoes",
        "price": 23,
        "sales": 99,
        "inventory": 79
    },
    {
        "product": "Pants",
        "price": 45,
        "sales": 46,
        "inventory": 58
    }
]

example formatter array:

[
    {
        data: 'product',
        format: (data) => {
            return '<em>' + data + '</em>';
        }
    },
    {
        data: 'price',
        format: (data) => {
            return '$' + data + '.00';
        }
    },
    {
        data: 'sales',
        format: (data) => {
            return '<span class="text-success">' + data + '</span>';
        }
    },
    {
        data: 'inventory',
        format: (data) => {
            return '<span class="text-primary">' + data + '</span>';
        }
    },
];

And here is the code that takes the formatter and applies it to the data:

for (let row of rows) {
    let renderedRow = {};
    for (let key in row) {
        let format = render.find(renderObject => renderObject.data === key);
        renderedRow[key] = format.format(row[key]);
    }
    renderedRows.push(renderedRow);
}
this.rows = renderedRows;

The loop iterates over the rows and then iterates over the object in the row. Inside the object’s loop, it finds the formatter (renderObject) with the matching key where data === key, and then uses the renderObject‘s format function to apply the formatting and push the data to a new array.

Because the formatting needs to be applied to the data in every row, I tried to just access it using the key, but since each key is inside an object inside an array I couldn’t figure out how to access that.

>Solution :

A simple thing you could do is take the find call and change it to a look-up table computed before the nested loop starts:

const formatters = Object.fromEntries(render.map(({ data, format }) => [data, format]));

for (let row of rows) {
    let renderedRow = {};
    for (let key in row) {
        let format = formatters[key];
        renderedRow[key] = format.format(row[key]);
    }
    renderedRows.push(renderedRow);
}

this.rows = renderedRows;

Leave a Reply