0

Using the post - Javascript data structure for fast lookup and ordered looping as a starting point, I am trying to build a spreadsheet like structure which will have 2-dimensional keys.

For a one dimensional key index, the solution linked to above uses this code:

function OrderedMap() {
    this.map = {};
    this._array = [];
}

OrderedMap.prototype.set = function(key, value) {
    // key already exists, replace value
    if(key in this.map) {
        this.map[key] = value;
    }
    // insert new key and value
    else {
        this._array.push(key);
        this.map[key] = value;
    }
};

Instead of a single key, I want to adapt this procedure for use with two keys, row and col. This is what I've come up with. But before I go down this path, is there a better / simpler way or a way which will have better performance with large data sets?

Update My concern with the code below is that it is row based. If I wish to act upon a row of data, it will be fairly efficient. However, if I wish to act upon a column of data, I have to cycle through each row and act upon the column within each row.

Is this an inherent problem working with 2-dimensional structures or is there a different way which works more at a cell level and can quickly loop either rows or columns?

This code will be used to manage data in a Javascript spreadsheet. Hence wanting the flexibility to navigate rows or columns quickly.

Thanks for your help.

function OrderedMap() {
    this.map = {};
    this._array = [];
}

OrderedMap.prototype.set = function (row, col, value) {
    if(row in this.map) {
 if(col in this.map[row]) {
     // key already exists, replace value
     this.map[row][col] = value;
 } else {
     // insert new key and value
     this._array[row].push(col);
     this.map[row][col] = value;
 } 
    }
    // insert new key and value
    else {
        this._array.push(row);
 this._array[row] = [];
 this._array[row].push(col);
        this.map[row] = {};
 this.map[row][col] = value;
    }
};

var map = new OrderedMap;
map.set(1, 1, {type: "cat"});
map.set(1, 2, {type: "mouse"});
map.set(2, 1, {type: "dog"});
map.set(3, 3, {type: "frog"});
console.log(map.map[2][1]);
mseifert
  • 5,390
  • 9
  • 38
  • 100
  • I'm not sure what you want, but it seems like you want a 2D array? – apple apple Dec 18 '18 at 07:53
  • @appleapple - A 2D array would work - however, if I wanted to start with cell [1000][1000] - I believe I would immediately have created an array with a large number of holes. It seems more efficient working with objects - even though an array is inherently an object. Plus looping would have to go through all those empty elements. – mseifert Dec 18 '18 at 07:56
  • How much data are you thinking it will have? A simple way would be to just keep a second mapping which is column based – Matthew Herbst Dec 18 '18 at 08:07
  • @MatthewHerbst - An example is 32000 rows with 40-100 columns. I'm working with historical stock data. But I can be working with many of these `sheets` simultaneously. And yes, that was exactly what I was considering. – mseifert Dec 18 '18 at 08:09
  • @mseifert I believe you would get sparse array in that way. so not much difference than object. While loop is a problem, I'm not sure it's good to skip empty cell. Plus spreadsheet usually not that sparse AFAIK. – apple apple Dec 18 '18 at 08:31

0 Answers0