简体   繁体   中英

javascript associative array access by key value

I have an array like this:

employees = [
        {
        "id": 1,
        "shift_id": 1,
        "days": {
            "2012-03-01": 1,
            "2012-03-02": 1,
            "2012-03-03": 1,
            "2012-03-04": 0,
            "2012-03-05": 0,
            "2012-03-06": 0
        }},
    {
        "id": 2,
        "shift_id": 1,
        "days": {
            "2012-03-01": 0,
            "2012-03-02": 1,
            "2012-03-03": 1,
            "2012-03-04": 1,
            "2012-03-05": 1,
            "2012-03-06": 0
        }},
    {
        "id": 3,
        "shift_id": 2,
        "days": {
            "2012-03-01": 0,
            "2012-03-02": 0,
            "2012-03-03": 1,
            "2012-03-04": 1,
            "2012-03-05": 1,
            "2012-03-06": 1
        }}

    ];

is there a way to access an element in this array using the id value? maybe something in jquery? like $(employees('id = 1');

Just loop through your array and check for the id:

var yourId = 1;
for (var i = 0, len = employees.length; i < len; i++) {
  if (employees[i].id == yourId) {
     // ...
  }
}

You can use a function like this, which filters the array appropriately:

var getEmployee = function (id) {
  return employees.filter(function(i) { return i.id == id; });
};

您可以使用此处记录的.grep()方法:

var employee = $.grep(employees, function(e) { return e.id == 1 })[0];

Well, there's a jQuery way of doing it:

var findElementById = function(elements, id) {
  return $.grep(elements, function(e) { return e.id === id; })[0];
}

Still I wonder why don't you just index the source array by id instead.

Or this:

$.each(employee, function(){
    if(this["id"] == 2){
        console.log(this);
    }
});

也许您正在寻找类似以下的内容:

$.grep(employees, function(n){return n.id==1});

As far as I am aware, in order to achieve that you would have to loop through them

 Array.prototype.getObjectById = function(x){
      var catcher = false, i = 0;
      while(!catcher){
        catcher = this[i].id == x ? this[i] : false;
        i++;
      }
      return catcher;
    }

This function should help. It will extend the array object so you can use it as myArray.getObjectbyId(id);

By design, this will return the first object that meets the criteria. You could extend it like so:

Array.prototype.getObjectsById = function(x){
  var catcher = [], i = 0;
  for(var i = 0; i < this.length; i++){
    if(this[i].id == value){
      catcher.push(this[i]);
    }
    i++;
  }
  return catcher.length == 1 ? catcher[0] : catcher;
}

This will return an array of objects if more than one object matches the criteria.

 Array.prototype.getObjectsByAttribute = function(x, criteria){
      if(!criteria){criteria = 'id';}
      var catcher = [], i = 0;
      for(var i = 0; i < this.length; i++){
        if(this[i].criteria == value){
         catcher.push(this[i]);
        }
        i++;
      }
      return catcher.length == 1 ? catcher[0] : catcher;
    }

This extends it further to look for any criteria.

I know this question is old, but for future reference if anyone else stumbles upon this question ...

Instead of trying to over-engineer a function to parse/examine your JSON, consider changing the structure of your data to suit its purpose.

Consider the example in the question:

 data =  [ {
    "id": 1,
    "shift_id": 1,
    "days": {
        "2012-03-01": 1,
        "2012-03-02": 1,
        "2012-03-03": 1,
        "2012-03-04": 0,
        "2012-03-05": 0,
        "2012-03-06": 0
    }}, { .. }, {...} ]

Structuring the data in this way only gives you sequential access to the objects with no way to lookup an object by a particular index. Array indices are generally meaningless in this context.

data[0] => { id : 1, .. }
data[1] => { id : 2, .. }

What happens if the id is non-sequential or alphanumeric?

Using an array wont help you search any faster, you'll still have to loop...

Instead consider using a hash table/object:

{
'id1' =>  { id : 1 , data : { ... } }, 
'id99' => { id : 99, data : { ... } },
'id2' =>  { id : 2 , data : { ... } },
}

You can use a string value for the key and get direct access to the data by doing something like:

 data['id2'] => { id : 2, ... }

Which will give you direct access to the data you want to find (by id). By simply re-organizing the structure of the data we were able to go from a O(n) search to an O(1) search.

Keep in mind that this method may work better for some solutions than others, and there are a number of other considerations to make.

This is just one approach to how you might solve a problem when you want to lookup data by a unique property.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM