scottm
scottm

Reputation: 28699

How can I create a javascript class and access an internal collection using and index/name lookup?

I currently have this:

function SystemCollection () {
    this.systems = [];

    this.getSystem = function (id) {
        for(var s in this.systems) {
            if(s.num == id)
                return s;
        };

        return null;
    };

    this.add = function (system) {
        this.systems.push(system);
    };

    this.count = systems.length;
};

In C#, I'd do something like this:

class SystemCollection {

  private List<System> _foo = new List<System>();

  public System this[int index]
  {
    get { _foo[index]; }
  }

  public System this[string name]
  {
    get { return _foo.Where( x => x.Name == name).SingleOrDefault(); }
  }
}

Upvotes: 1

Views: 803

Answers (3)

ChaosPandion
ChaosPandion

Reputation: 78282

I get the feeling that this C# like list will suit your purposes.

Code

function List() {

    this.count = 0;

    this.add = function(item) {
        this[this.count] = item;
        this.count++;
    }

    this.remove = function(index) {
        delete this[index];
        this.count--;
    }

}

Example

var list = new List();
list.add(1);
alert(list.count);
list.add(2);
alert(list.count);
alert(list[1]);

Upvotes: 0

Christian C. Salvad&#243;
Christian C. Salvad&#243;

Reputation: 827742

Seems that you are trying to do a sort of key/value pair (systemId / systemName) collection.

The systems array should be private, handled internally only by the add and get methods.

Also since it is an array, you shouldn't use the for...in statement, a normal for loop it's enough, I think something like this:

API tests:

var test = new SystemCollection();
test.add(1, "System One");
test.add(2, "System Two");

test.count(); // 2
test.getSystemByName("System Two"); // Object id=2 name=System Two
test.getSystemById(1); // Object id=1 name=System One

Implementation:

function SystemCollection () {
  var systems = []; // private array

  // generic function to search by a property name
  function getSystem (value, propName) {
    var i, s;
      for(i = 0; i < systems.length; i++) {
        s = systems[i];
         if(s[propName] == value) {
            return s;
         }
      }
      // will return undefined if this point is reached
   }

   this.getSystemByName = function (name) {
     return getSystem(name, "name");
   };

   this.getSystemById = function (id) {
     return getSystem(id, "id");
   };

   this.add = function (systemId, systemName) {
     systems.push({id: systemId, name: systemName});
   };

   this.count = function () {
     return systems.length;
   };
}

Upvotes: 1

Zoidberg
Zoidberg

Reputation: 10333

I don't think you can override the this[] operator in javascript. But what you could do is this. I am assuming system has a property called name

this.add = function(system){
     this[system.name] = system;
}

then you can use the collection like this

collection[systemName];

Should do the trick, I hope. If this is not sufficient, then you can augment the value stored under the system name by wrapping it in an object or something like that.

Upvotes: 1

Related Questions