Есть ли более эффективный способ выбора конкретного объекта внутри массива объектов - PullRequest
2 голосов
/ 23 мая 2011

Учитывая следующую структуру данных

var things = [{ "name": "thing1", "sex": "male"},
              { "name": "thing2", "sex": "female"}];

Я хотел бы иметь возможность искать в этом массиве объектов и извлекать определенный объект.

В настоящее время у меня написан следующий код

function selectElementByName (name) { 

  var returnObject;

  for (var i = 0; i < things.length; i++) {

    if (things[i].name === name) {

        returnObject = things[i];
    }
  } 


  if ( returnObject === undefined) { 
    console.log("Object not found");
  }

  return returnObject;
}

JsFiddle можно найти здесь

Есть ли более эффективный способ сделать это?

Ответы [ 3 ]

5 голосов
/ 23 мая 2011

Вы можете сделать ранний выход, когда объект найден, так что вам не придется перебирать оставшуюся часть массива:

function selectElementByName(name) { 
  for (var i = 0; i < things.length; i++) {
    if (things[i].name === name) {
      return things[i];
    }
  }
  console.log("Object not found");
}

(Это, однако, изменит поведение, если есть дубликаты, так что он возвращает первый найденный объект вместо последнего.)


Если имена уникальны, вы можете использовать их в качестве ключа и сохранять объекты в объекте, а не в массиве:

var things = {
  "thing1": { "name": "thing1", "sex": "male"},
  "thing2": { "name": "thing2", "sex": "female"}
};

Тогда вам не понадобится цикл, чтобы найти объект:

function selectElementByName(name) { 
  return things[name];
}

Если вам нужны объекты в массиве, вы все равно можете создать индекс для поиска, если массив не меняется так часто:

var thingsNameIndex = {};
for (var i = 0; i < things.length; i++) {
  thingsNameIndex[things[i].name] = i;
}

Теперь вы можете использовать индекс, чтобы найти объект:

function selectElementByName(name) { 
  return things[thingsNameIndex[name]];
}

Поскольку вы должны обновить или воссоздать индекс, как только массив изменится, это будет полезно только в том случае, если вы выполняете поиск в массиве гораздо чаще, чем изменяете массив.

0 голосов
/ 23 мая 2011

Вы можете сломать, как только оно будет найдено:

for (var i = 0; i < things.length; i++) {
    if (things[i].name === name) {                        
        returnObject = things[i];
        break;
    }
} 
0 голосов
/ 23 мая 2011

В более поздних версиях JavaScript:

var selectElementByName = function(name) {
    // This will fetch all items that match the filter
    // and place them in a new array
    var items = things.filter(function(item) {
        return item.name === name;
    });

    // If there isn't anything in the array, log the error and return.
    if (!items.length) {
        console.log("Object not found");
        return;
    }

    // Return the first matched element in the array.
    return items[0];
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...