the_lotus
the_lotus

Reputation: 12748

Mixing Index Array with "Associative Array"

Since I need to access my items sometime by index and sometime by code. Is it a good idea to mix integer index with string index?

Note that the code, index, amount of items never changes after the data is loaded.

I'm thinking of doing something like this, where the same object is pushed and set as a hashtable.

function DataInformation(code, dataValue) {
    this.code = code;
    this.dataValue = dataValue;
}

var dataList = [];

function fillDataList() {
    addNewData(new DataInformation("C1", 111));
    addNewData(new DataInformation("C2", 222));
    addNewData(new DataInformation("C3", 333));
}

function addNewData(newData) {
    dataList.push(newData);
    dataList[newData.code] = newData;
}

Then I would be able to access the object with either:

dataList[0].dataValue
dataList["C1"].dataValue

Before I used to loop to find the item.

function findItemByCode(code) {
    for (var i = 0; i < dataList.length; i++) {
        if (dataList[i].code == code) {
            return dataList[i];
        }
    }

    return null;
}

findItemByCode("C1").dataValue

Upvotes: 0

Views: 371

Answers (2)

Vladu Ionut
Vladu Ionut

Reputation: 8193

Here is my try using Proxies

// Code goes here

function DataInformation(code, dataValue) {
  this.code = code;
  this.dataValue = dataValue;
}

var _dataList = [];
var dataList = new Proxy(_dataList, {
  get: function(target, name) {
    if (target && target.myMap && target.myMap[name]) return target[target.myMap[name]];
    return target[name];
  },
  set: function(obj, prop, value) {
    // The default behavior to store the value
    obj.myMap = obj.myMap || {};
    obj.myMap[value.code] = prop;
    obj[prop] = value;
    return true;
  }
});

function fillDataList() {
  addNewData(new DataInformation("C1", 111));
  addNewData(new DataInformation("C2", 222));
  addNewData(new DataInformation("C3", 333));
}

function addNewData(newData) {
  dataList.push(newData);
}

fillDataList();

console.log(dataList[0].dataValue);
console.log(dataList["C1"].dataValue);

Upvotes: 0

Tomalak
Tomalak

Reputation: 338188

Do you ever need to iterate dataList in strict order? Or is it just a bag of items for which you want random access by a certain key?

If ordered iteration is not a concern, use an object instead of an array. Watch out for key clashes, though.

var dataList = {};

function addNewData(newData) {
    dataList[newData.code] = newData;
    dataList[newData.dataValue] = newData;
}

// that's it, no other changes necessary

If key clashes can occur - or ordered iteration is necessary, or if you just want to make it particularly clean, use an array and an accompanying index object.

var dataList = [];
var dataIndex = {
    byCode: {},
    byValue: {}
};

function addNewData(newData) {
    dataList.push(newData);
    dataIndex.byCode[newData.code] = newData;
    dataIndex.byValue[newData.dataValue] = newData;
}

Upvotes: 3

Related Questions