0

I have a two dimensional array that I need to perform read and write action on from various angles. Sometimes I need to get/set a single row (easy of course) and sometimes I need to get/set a single column or even just a single cell but coming from a column perspective.

Let me try to explain what I want to achieve:

function myFunction() {

  var myArray = [['a1','b1'],['a1','b1']];

  var ds = new DataStructure(myArray);
  console.log(ds) // -> [['a1','b1'],['a1','b1']]

  console.log(da[0]) // -> ['a1','b1']
  console.log(da[1]) // -> ['a2','b2']

  console.log(da.cols[0]) // -> ['a1','a2']
  console.log(da.cols[1]) // -> ['b1','b2']
  da.cols[0] = ['A1','A2']
  console.log(da.cols[0]) // -> ['A1','A2']
  da.cols[1][1] = 'Q2'
  console.log(da.cols[1]) // -> ['b1','Q2']

  console.log(ds) // -> [['A1','b1'],['A1','Q1']]

  console.log(myArray) // -> [['A1','b1'],['A1','Q1']]
}

So basically I want to have a wrapper to my original data structure and all get/set access to it should work directly on the original structure (by reference I reckon).

Any idea?

I have tried to use Proxy() and Object.defineProperty() to define custom getters/setters. It kind of works but as soon as I access into a column i.e. ds.cols[0][0] it doesn't work anymore.

3
  • How do you get 'a2' and 'b2'? The data does not have such strings in it. Also, da is not even declared.
    – holydragon
    Commented Jun 14 at 6:41
  • 1
    I have tried - show what you tried - perhaps it's an easy fix Commented Jun 14 at 7:00
  • 1
    Do you have to treat cols as a property? Why not use methods, da.rows(1) and da.cols(1)? Then you don't need any fancy coding like getters or proxies.
    – Barmar
    Commented Jun 14 at 14:24

1 Answer 1

0

You need create custom class which will encapsulate and expose setter and getters set/get values specified rows and columns.

In the below example refer the how values being set/get in myFunction method.

Refer the below example:

class DataStructure {
  constructor(array) {
    this.array = array;
    this.cols = new Proxy({}, this.getColumnHandler());
  }

  getColumnHandler() {
    return {
      get: (target, prop) => {
        if (typeof prop === 'symbol') return target[prop];
        const colIndex = Number(prop);
        if (isNaN(colIndex)) return undefined;
        return this.array.map(row => row[colIndex]);
      },
      set: (target, prop, value) => {
        const colIndex = Number(prop);
        if (isNaN(colIndex)) return false;
        value.forEach((val, rowIndex) => {
          if (this.array[rowIndex]) {
            this.array[rowIndex][colIndex] = val;
          }
        });
        return true;
      }
    };
  }

  getRow(rowIndex) { // Get row by index
    return this.array[rowIndex];
  }

  setRow(rowIndex, row) {
    this.array[rowIndex] = row;
  }

  getCell(rowIndex, colIndex) { // Get cell by row index and column index
    return this.array[rowIndex][colIndex];
  }

  setCell(rowIndex, colIndex, value) { Set cell by row index and column index
    this.array[rowIndex][colIndex] = value;
  }
}


function myFunction() {
  var myArray = [['a1', 'b1'], ['a2', 'b2']];
  var ds = new DataStructure(myArray);
  ds.cols[0] = ['A4', 'A2']; // Set column by index 
  ds.setRow(0,['A9', 'A0']) // Set row by index 
  ds.setCell(1,1,'Q2'); // Set cell by column and row 
  return ds;
}

console.log(JSON.stringify(myFunction));

1
  • 1
    Thank you! That solves my problem just perfectly! Commented Jun 16 at 6:01

Not the answer you're looking for? Browse other questions tagged or ask your own question.