Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Обращение к объекту по значению свойства (https://javascript.ru/forum/misc/64960-obrashhenie-k-obektu-po-znacheniyu-svojjstva.html)

neon_tmn 16.09.2016 13:20

Обращение к объекту по значению свойства
 
Здравствуйте. Возможно такое и не возможно сделать.
Есть объект
{num: [
      {"id": 1, "name": "Один"},
      {"id": 2, "name": "Два"},
      {"id": 3, "name": "Три"}
]
}


Я знаю цифру 2 и хочу получить слово "Два".
Как мне, зная цифру "2" обратиться к объекту num так, чтобы получить значение "Два"?
То есть, я знаю имя объекта, я знаю одно значение свойства и по нему хочу получить значение второго свойства.
Пример привел элементарный, по идее в id может быть не порядковая цифра, а вообще слово мне известное.

Manyasha 16.09.2016 13:38

neon_tmn, здравствуйте.
Наверное, как-то проще можно... Как вариант:
var obj = {num: [
      {"id": 1, "name": "Один"},
      {"id": 2, "name": "Два"},
      {"id": 3, "name": "Три"}
]
}

function getName(obj, id){
  var filt = obj.filter(function(e){
    return e.id === id;
  });
  if (filt.length == 1){
    return filt[0].name;
  }else if(filt.length > 1){
    return "id is not unique";
  }else{
    return "not found";
  }
}

for (var i = 0; i<=3; i++){
  alert(getName(obj.num, i));
}

neon_tmn 16.09.2016 13:51

Надо же.. весь интернет перерыл, вроде как filter работает с массивами и не думал, что к объектам он применим.
Благодарю.

Manyasha 16.09.2016 14:01

Цитата:

Сообщение от neon_tmn (Сообщение 428849)
filter работает с массивами и не думал, что к объектам он применим.

мы же подаем в функцию obj.num, а это массив! C объектом и не сработало бы.

neon_tmn 16.09.2016 14:03

Цитата:

Сообщение от Manyasha (Сообщение 428850)
мы же подаем в функцию obj.num, а это массив! C объектом и не сработало бы.

Понял. Спасибо большое. Поставил плюсик к карме.

neon_tmn 16.09.2016 14:34

Как-то можно динамически задавать наименование return filt[0].name;
? То, есть, например у меня на самом деле много свойств, есть name, есть description, есть image.
Сделать бы одну функцию для получения любого из указанных свойств.


function getName(obj, fieldname, id){  // добавил fieldname
  var filt = obj.filter(function(e){
    return e.id === id;
  });
  if (filt.length == 1){
    return filt[0].name; // Если вместо name поставлю [B]fieldname[/B], то не сработает, пробовал в квадратных скобках еще писать [B][fieldname][/B], тоже не сработало.
  }else if(filt.length > 1){
    return "id is not unique";
  }else{
    return "not found";
  }
}

}

neon_tmn 16.09.2016 15:03

Все из-за собственной невнимательности. Вот так работает return filt[0][field]; и в вызове функции нужно наименование свойства (или ключа, раз массив) писать в кавычках.

warren buffet 17.09.2016 18:44

В таких случаях прибегают к избыточности данных, чтобы не мучить браузер.

var num={
      1:{"id": 1, "name": "Один"},
      2:{"id": 2, "name": "Два"},
      3:{"id": 3, "name": "Три"}
},

search=2;

if(search in num)
   console.log(num[search].name);


Понял?

warren buffet 17.09.2016 18:49

Почему избыточность. Потому что нельзя выкидывать id из объекта, несмотря на идентичное значение в качестве ключа. Вот смотри

var num={
      1:{"id": 1, "name": "Один"},
      2:{"id": 2, "name": "Два"},
      3:{"id": 3, "name": "Три"}
},

search=2,

stdout=function(obj){

    console.log('ID='+obj.id + '; Name='+obj.name);

};

if(search in num)
   stdout(num[search]);


Если id выкинуть, то придется передавать его отдельно. Даже если ты веришь, что избыток не понадобится - оставь его. Мемори на клиенте как гавна.

warren buffet 17.09.2016 18:57

Цитата:

Сообщение от neon_tmn
То, есть, например у меня на самом деле много свойств

Свойства в списках находятся в полях. Так и говорят - найти значение по полю такому-то. Ну да, тогда дописываешь аргумент для имени поля и проверку.

Но по идешникам получать доступ лучше по ключам.

А вообще если так дело у тебя пойдет дальше, тебе придется писать SQL для браузера. )))

warren buffet 17.09.2016 19:07

А зачем вам эти фильтры и прочая тряхомудия?

function myLovelySearch(arr,val,fld){

   fld=fld||'id';

   for(var i=0;i<arr.length;i++)
       if(typeof arr[i][fld]!=='undefined' && val==arr[i][fld])
          return arr[i];

}

var found = myLovelySearch(obj.num,'Два','name');
console.log(found.id);


It's all folks. Проверка на ундефайнед нужна на случай, если такого поля там нет вообще.

Что делать с нотфаунд в ООП - это уже отдельный стон.

neon_tmn 14.10.2016 08:06

Цитата:

Сообщение от warren buffet (Сообщение 428975)
А зачем вам эти фильтры и прочая тряхомудия?

function myLovelySearch(arr,val,fld){

   fld=fld||'id';

   for(var i=0;i<arr.length;i++)
       if(typeof arr[i][fld]!=='undefined' && val==arr[i][fld])
          return arr[i];

}

var found = myLovelySearch(obj.num,'Два','name');
console.log(found.id);


It's all folks. Проверка на ундефайнед нужна на случай, если такого поля там нет вообще.

Что делать с нотфаунд в ООП - это уже отдельный стон.


До этого вы писали примеры с IN, не помогут. вы предлагаете искать строку в заданном индексе, например индекс 2. А если у меня 10 индексов и я не знаю, в каком из них будет искомое значение. перебирать циклом? ок.
Дальше, последнее ваше сообщение циклом обходит весь массив. Это в принципе не плохо, но в моем реальном случае получается так, что у меня есть массив из 10 элементов и есть 20 искомых значений. По идее мне нужно будет делать цикл по значение из 20 штук и на каждое делать вложенный цикл на поиск значения в 10 элементах. Долговато это будет.

warren buffet 14.10.2016 08:10

Цитата:

Сообщение от neon_tmn
10 элементов и есть 20 искомых значений


Забыл как умножить 10 на 20? Я помню, будет 200. Не многовато ли? Ну как тебе сказать, это примерно как если пописить в тихий океан и начать волноваться о затоплении Венеции.

У тебя какой комп? 286 штоле? Какие блин 200? 200000 не заметишь нифига. Два миллиона итераций еще может будет заметно. Там же итерации микроскопические, хера ли тут думать, все равно у тебя нет другого способа.

Нет, есть еще способ - можешь проиндексировать все поля. Приколись.

warren buffet 14.10.2016 08:16

Индексация знаешь как делается? Тебе ее придется сделать скриптом, получить из него скрипт, добить индексы в исходный код и впоследствии поддерживать все индексы когда данные будут удаляться, добавляться и изменяться.

Нравится? Вот так. Итерируй свои 200, для современного браузера это с гулькин член задача.

warren buffet 14.10.2016 08:22

И вообще задолбали оптимизаторы. Это дело по Фрейду знаешь как называется? - Анальная фиксация. Чтобы избавиться от этой фиксации, посмотри исходники хотя бы этого форума, он весь на жабе скрипучей. И еще один способ - задумайся о количестве итераций и ресурсов браузера для размочки жипега 1200 на 800 с последующей бикубической интерполяцией до 458 на сколько там. Одна такая картинка может зохавать в 100 раз больше, чем все твои скрипты вместе взятые.


Часовой пояс GMT +3, время: 05:09.