Подтвердить что ты не робот

Как получить индекс объекта по его свойству в javascript

Например, у меня есть:

var Data = [
    {id_list:1, name:'Nick',token:'312312'},{id_list:2,name:'John',token:'123123'}
    ]

Затем я хочу, чтобы отсортировать/отменить этот объект по имени, например. Я получаю что-то вроде этого:

var Data = [
    {id_list:2,name:'John',token:'123123'},{id_list:1, name:'Nick',token:'312312'}
    ]

И теперь я хочу знать индекс объекта с свойством name= 'John', чтобы получить значение маркера свойства.

4b9b3361

Ответ 1

Как показывают другие ответы, наилучшим способом является цикл через массив. Но я бы поставил его в свою собственную функцию и сделал бы это немного более абстрактным:

function findWithAttr(array, attr, value) {
    for(var i = 0; i < array.length; i += 1) {
        if(array[i][attr] === value) {
            return i;
        }
    }
    return -1;
}

var Data = [
    {id_list: 2, name: 'John', token: '123123'},
    {id_list: 1, name: 'Nick', token: '312312'}
];

С этим вы можете не только найти тот, который содержит "Джон", но вы можете найти, который содержит токен "312312":

findWithAttr(Data, 'name', 'John'); // returns 0
findWithAttr(Data, 'token', '312312'); // returns 1
findWithAttr(Data, 'id_list', '10'); // returns -1

EDIT: Обновленная функция для возврата -1, если не найдена, поэтому она следует той же конструкции, что и Array.prototype.indexOf()

Ответ 2

Поскольку часть сортировки уже ответила. Я просто собираюсь предложить еще один элегантный способ получить indexOf свойства в вашем массиве

Ваш пример:

var Data = [
    {id_list:1, name:'Nick',token:'312312'},
    {id_list:2,name:'John',token:'123123'}
]

Ты можешь сделать:

var index = Data.map(function(e) { return e.name; }).indexOf('Nick');

Array.prototype.map недоступен в IE7 или IE8. Совместимость с ES5

И здесь это с синтаксисом ES6 и стрелкой, что еще проще:

const index = Data.map(e => e.name).indexOf('Nick');

Ответ 3

Если у вас все в порядке с ES6. Теперь у массивов есть функция findIndex. Это означает, что вы можете сделать что-то вроде этого:

const index = Data.findIndex(item => item.name === 'John');

Ответ 4

var index = Data.findIndex(item => item.name == "John")

Это упрощенная версия:

var index = Data.findIndex(function(item){ return item.name == "John"})

От mozilla.org:

Метод findIndex() возвращает индекс первого элемента в массиве, который удовлетворяет предоставленной функции тестирования. В противном случае возвращается -1.

Ответ 5

Только известный мне путь - это цикл по всему массиву:

var index=-1;
for(var i=0;i<Data.length;i++)
  if(Data[i].name==="John"){index=i;break;}

или регистр нечувствителен:

var index=-1;
for(var i=0;i<Data.length;i++)
  if(Data[i].name.toLowerCase()==="john"){index=i;break;}

В индексе переменной результата содержится индекс объекта или -1, если не найден.

Ответ 6

прототипный способ

(function(){
  if (!Array.prototype.indexOfPropertyValue){
    Array.prototype.indexOfPropertyValue = function(prop,value){
      for (var index = 0; index < this.length; index++){
        if (this[index][prop]){
          if (this[index][prop] == value){
            return index;
          }
        }
      }
      return -1;
    }
  }
 })();
 // usage:
 var Data = [
 {id_list:1, name:'Nick',token:'312312'},{id_list:2,name:'John',token:'123123'}];
 Data.indexOfPropertyValue('name','John'); // returns 1 (index of array);
 Data.indexOfPropertyValue('name','Invalid name') // returns -1 (no result);
 var indexOfArray = Data.indexOfPropertyValue('name','John');
 Data[indexOfArray] // returns desired object.

Ответ 7

Почему вы не используете небольшой рабочий процесс?

Создайте новый массив с именами в качестве индексов. после этого все поисковые запросы будут использовать индексы. Итак, только один цикл. После этого вам не нужно прокручивать все элементы!

var Data = [
    {id_list:1, name:'Nick',token:'312312'},{id_list:2,name:'John',token:'123123'}
    ]
var searchArr = []
Data.forEach(function(one){
  searchArr[one.name]=one;
})
console.log(searchArr['Nick'])

http://jsbin.com/xibala/1/edit

живой пример.

Ответ 8

Вы можете использовать Array.sort, используя пользовательскую функцию в качестве параметра, чтобы определить ваш метод сортировки.

В вашем примере это даст:

var Data = [
    {id_list:1, name:'Nick',token:'312312'},{id_list:2,name:'John',token:'123123'}
]

Data.sort(function(a, b){
    return a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
});

alert("First name is : " + Data[0].name); // alerts 'John'
alert("Second name is : " + Data[1].name); // alerts 'Nick'

Функция сортировки должна возвращать либо -1, если a должно быть до b, 1, если a должно прийти после b и 0, если оба они равны. Вам нужно определить правильную логику в вашей сортировке для сортировки массива.

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

Ответ 9

Просто пройдите через массив и найдите позицию:

var i = 0;
for(var item in Data) {
    if(Data[item].name == 'John')
        break;
    i++;
}
alert(i);

Ответ 11

Расширенный ответ Криса Пикетта, потому что в моем случае мне нужно было искать глубже одного уровня атрибута:

function findWithAttr(array, attr, value) {
  if (attr.indexOf('.') >= 0) {
    var split = attr.split('.');
    var attr1 = split[0];
    var attr2 = split[1];
    for(var i = 0; i < array.length; i += 1) {
      if(array[i][attr1][attr2] === value) {
        return i;
      }
    }
  } else {
    for(var i = 0; i < array.length; i += 1) {
      if(array[i][attr] === value) {
        return i;
      }
    }
  };
};

Вы можете передать 'attr1.attr2' в функцию

Ответ 12

Как насчет этого?

Data.indexOf(_.find(Data, function(element) {
  return element.name === 'John';
}));

Предполагая, что вы используете lodash или underscorejs.

Ответ 13

var fields = {
teste:
{
    Acess:
    {
        Edit: true,
      View: false

      }
 },
teste1:
{
    Acess:
    {
        Edit: false,
      View: false

      }
  }
};

console.log(find(fields,'teste'));
function find(fields,field){
    for(key in fields){
        if(key == field){
        return true;
    }
}
return false;
}

Если у вас есть один объект с несколькими объектами внутри, если вы хотите знать, включен ли какой-либо объект в объект-мастер, просто поместите find (MasterObject, "Object to Search" ), эта функция вернет ответ, если существует или нет ( TRUE или FALSE), я надеюсь, что с этим справится, можно увидеть пример JSFiddle.

Ответ 14

let indexOf = -1;
let theProperty = "value"
let searchFor = "something";

theArray.every(function (element, index) {

    if (element[theProperty] === searchFor) {
        indexOf = index;
        return false;
    }
    return true;
});

Ответ 15

В качестве альтернативы немецкому Attanasio Ruiz ответьте, вы можете исключить второй цикл, используя Array.reduce() вместо Array.map();

var Data = [
    { name: 'hypno7oad' }
]
var indexOfTarget = Data.reduce(function (indexOfTarget, element, currentIndex) {
    return (element.name === 'hypno7oad') ? currentIndex : indexOfTarget;
}, -1);

Ответ 16

collection.findIndex(item => item.value === 'smth') !== -1