Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Поиск объектов в массиве (https://javascript.ru/forum/misc/39173-poisk-obektov-v-massive.html)

Lynatik 18.06.2013 23:02

Поиск объектов в массиве
 
Доброго времени суток всем.
Подвернулось задание- Имеется массив с объектами, имеющими поле «id» с уникальными значениями в пределах этого массива. Требуется искать объекты в этом массиве, имеющие определенное значение «id». Плюсы и минусы.

Самый очевидный способ(тупо перебрать массив до попадания) я сделал. Сначала для теста массив создал.
function Obj(id){
	this.id = id
}

var arr = [];

for (var j = 0; j < 5000000; j++){
	var obj = new Obj(j);
	arr.push(obj);	
}

var init="time";
const FINDID = 4999999;

function findEl(array) {
	for (var i = 1; i < (array.length + 1); i++){
		if (array[i].id == FINDID){
			console.log ("this is " + i + " element");
			break
		}
	}
}
console.time(init);
findEl(arr);
console.timeEnd(init);


Написал, что если большое количество объектов, то поиск возможно долгий будет. По времени функция такая ~120.000ms выполняется.

НО. Какие варианты еще есть? Может кто поможет?

Может еще взять все объекты из массива, склеить их в строку, разделяя чем- нибудь, типа (obj1.id тут уже строковая будет)
var str = "obj1.id#obj2.id#и так далее";


и потом уже искать в строке. Но это порнография какая- то уже получается, да и, наверняка долго будет.
Я новичок в программировании, особо не хайте:)
Спасибо огромное тому, кто наведет на путь истинный

рони 18.06.2013 23:18

Цитата:

Сообщение от Lynatik
for (var i = 1; i < (array.length + 1); i++){

интересно куда делся 0 элемент массива и существует ли элемент array.length ?

Lynatik 18.06.2013 23:29

Я затупил что - то)) Спасибо
for (var i = 0; i < array.length; i++){
		if (array[i].id == FINDID){
			console.log ("this is " + (i + 1) + " element");
			break
		}
	}


А по самому варианту поиска подскажет кто- нибудь?

рони 18.06.2013 23:45

Lynatik,
если вы сами формируите массив -- то можно создать обьект где ключами будут id, а значениями индексы массива, тогда поиск будет почти мгновенный.

Lynatik 19.06.2013 00:22

Цитата:

Сообщение от рони (Сообщение 257098)
если вы сами формируите массив -- то можно создать обьект где ключами будут id, а значениями индексы массива, тогда поиск будет почти мгновенный.

Но тогда же у нас все равно будет много ключей и индексов и все равно придется их перебирать...не понял я что-то((
Можно ли, пожалуйста, немного поподробнее? желательно с парой строчками кода

nerv_ 19.06.2013 00:28

бинарный поиск

Lynatik 19.06.2013 00:41

nerv_ спасибо, но это не то вроде. Вдруг id не по порядку идут

рони вроде понял, про что Вы говорите.
но что- то не допру как сам цикл сделать, где ассоциативный массив заполняем id-шниками

nerv_ 19.06.2013 01:19

Цитата:

Сообщение от Lynatik
спасибо, но это не то вроде. Вдруг id не по порядку идут

сортировку для чего придумали? Какой вопрос, такой ответ.

var hash = {};

hash[ 'key' ] = 'value';

alert( hash.key );

рони 19.06.2013 01:47

Цитата:

Сообщение от Lynatik
как сам цикл сделать, где ассоциативный массив заполняем id-шниками

var hash = {};
 function Obj(id){
	this.id = id
}
var arr = [];
for (var j = 0; j < 5000000; j++){
    hash[j] = j;
    var obj = new Obj(j);
	arr.push(obj);
}

var init="time";
const FINDID = 4999999;

function findEl() {
   return hash[FINDID]

}
console.time(init);
findEl(arr);
console.timeEnd(init);

Dim@ 19.06.2013 11:20

Lynatik,
Цитата:

Сообщение от рони
если вы сами формируите массив -- то можно создать обьект где ключами будут id, а значениями индексы массива, тогда поиск будет почти мгновенный.

А если хешей не будет и массив не упорядочен, то можно использовать такой поиск:
function Obj(id){
    this.id = id
}
 
var arr = [];
 
for (var j = 0; j < 5000000; j++){
    var obj = new Obj(j);
    arr.push(obj); 
}
 
var init="time";
const FINDID = 4999999;
 
function findEl(array) {
    array[array.length] = new Obj(FINDID);
    for (var i = 0; array[i].id != FINDID ; i++){}
    if (i == (array.length - 1))
         alert( "Искомое значение не найдено." );
    else
         alert( i );
}
console.time(init);
findEl(arr);
console.timeEnd(init);

Lynatik 19.06.2013 12:46

рони Спасибо, все понял
Dim@ Спасибо за вариант, но он долгий очень

накатал несколько вариантов за ночь

Радует, что есть люди, готовые помочь. Человеческое спасибо всем!

Hekumok 19.06.2013 14:27

function Obj(id) {
  this.id = id ;
}
for(var arr = [], j = 0; j < 5000000; j++)
  arr.push(new Obj(j)) ;
var init = "time" ;
const FINDID = 4999999 ;
function findEl(array) {
  var i = 0 ;
  array.some(function(obj) {
    i++ ;
    return obj.id === FINDID ;
  }) ;
  console.log("this is " + i + " element") ;
}
console.time(init) ;
findEl(arr) ;
console.timeEnd(init);

Dim@ 19.06.2013 23:00

Lynatik,
В каком смысле долгий?

nerv_ 20.06.2013 00:23

ASSembler, http://javascript.ru/forum/misc/3917...tml#post257102

Lynatik 20.06.2013 01:40

В задании ничего не было сказано про id. только то, что они уникальные.
Задание вроде сделал и отдал уже.
Спасибо огромное всем за советы.
Реально помогаете. А я учусь. Скоро тоже кому- нибудь смогу помогать)

bes 20.06.2013 23:56

Цитата:

Сообщение от Lynatik
Имеется массив с объектами

в массиве хранятся не объекты :)

Hekumok 21.06.2013 00:11

bes, а что же тогда?

Lynatik 21.06.2013 00:18

bes,
действительно, что вы имеете ввиду?? о_О

bes 21.06.2013 00:35

Цитата:

Сообщение от Hekumok
bes, а что же тогда?

Цитата:

Сообщение от Lynatik
bes,
действительно, что вы имеете ввиду?? о_О

я думаю, что ссылки :)
в спецификации они представлены объектами внутреннего типа Reference
http://es5.javascript.ru/x8.html#x8.7
сами объекты, насколько я понимаю, хранятся обычно в куче (heap)

eugasl 21.06.2013 22:00

Как вариант можно еще так:

function Obj(x) {
      this.id = x; 
      this.toString = function() {
          return x;
      };
 }
  var arr = [new Obj(1), new Obj(2), new Obj(3)];
  console.log(arr[arr.join(',').indexOf('2')-1]); // искомый объект. Тут хорошо бы еще проверку, хотя все равно вернет undefined

nerv_ 21.06.2013 23:52

eugasl, а если это объекты?

eugasl 22.06.2013 10:12

Цитата:

Сообщение от nerv_ (Сообщение 257732)
eugasl, а если это объекты?

Не понял вопроса...

eugasl 22.06.2013 10:23

Если я правильно вас понял, что если
arr = [{id: 1}, {id: 2}, {id: 3}];

?

Как вариант можно сделать map
var arr = [{id: 1}, {id: 2}, {id: 3}];
arr = arr.map(function(item){item.toString = function(){return this.id}; return item});
console.log(arr[arr.join(',').indexOf('2')-1]);

nerv_ 22.06.2013 11:18

[div, div, div]

eugasl 22.06.2013 12:43

Условие задачи другое.
Но в вашем случае не вижу проблемы, все тоже самое


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