views:

70

answers:

3

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(); }
  }
}
+1  A: 

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.

Zoidberg
I think that will probably work for what I'm doing. Can you tell me exactly what's going on there? Is it just storing the system in some generic internal collection?
scottm
Its actually storing it in a property.myObject['someval'] = val is the same as putting myObject.someval = val
Zoidberg
+1  A: 

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;
   };
}
CMS
why not use for...in?
scottm
The `for...in` statement is meant to be used to iterate over **object properties**, the problem with this statement when you use it with arrays is that it crawls up the prototype chain, and if the `Array.prototype` has been extended, those extended properties will be also iterated (if you don't use hasOwnProperty) and also, this statement doesn't ensure anyhow the order of iteration, so in conclusion, if you want to iterate an array, go for a normal `for` or `while` loop to avoid problems. More info about `for...in`: http://is.gd/4Pa2m
CMS
A: 

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]);
ChaosPandion