Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   delete и функции (https://javascript.ru/forum/misc/11004-delete-i-funkcii.html)

KOLANICH 01.08.2010 23:05

delete и функции
 
есть массив
я создал функкцию, которая проверяет элемент массива на условие и в зависимо от результата проверки удаляет или нет эл-т массива

после прохода функцией по массиву (в цикле) все эл-ты на месте, хотя сработало условие для удаления (причём довольно много раз)

function fakeCheck(el){
		if(el.style.display=='none'||el.type=="hidden"||el.style.zIndex<=-3){
			console.log("deleting ", el)
			delete el;
			return false;
		}
		return true;
	}

JsLoveR 01.08.2010 23:08

el=null;

Gvozd 01.08.2010 23:08

судя по вашему коду, el - это элемент DOM
значит и удалять его надо соответствующим образом, через removeChild

если же вы хотите удалить элементы из массива, то и удаляйте из него.
el - всего лишь ссылается на элемент в DOM
он ничего не знает о том, в какой массив вы его засунули вовне

KOLANICH 01.08.2010 23:10

да, элемент дом
но мне не нужно удалять сам элемент
мне нужно удалить ссылку на него в массиве, полученном через getElemetsByTagName
короче мне нужно "профильтровать" массив

Sweet 01.08.2010 23:54

Почитайте здесь и узнаете, как "профильтровать" массив:)

x-yuri 02.08.2010 01:14

во-первых, из HTMLCollection нельзя ничего удалять. Во-вторых, delete предназначен для удаления свойств объектов, а не элементов массива. В-третьих, массивы фильтруются с помощью метода filter. Здесь сказано, как использовать его кроссбраузерно. Для копирования массивов можно использовать следующую функцию (в частности работает при копировании из HTMLCollection и arguments)
function $A(iterable){
	if (iterable.item){
		var l = iterable.length, array = new Array(l);
		while (l--) array[l] = iterable[l];
		return array;
	}
	return Array.prototype.slice.call(iterable);
};

в результате код будет выглядеть как-то так:
var divs = document.getElementsByTagName('div');
divs = $A(divs).filter(function(el){
    return el.style.display != 'none' &&
        el.type=="hidden" &&
        el.style.zIndex<=-3;
});

Kolyaj 02.08.2010 12:53

Цитата:

Сообщение от KOLANICH
мне нужно удалить ссылку на него в массиве, полученном через getElemetsByTagName

getElementsByTagName возвращает не массив.

Цитата:

Сообщение от x-yuri
Во-вторых, delete предназначен для удаления свойств объектов, а не элементов массива.

Но т.к. элемент массива это такое же свойство, он таки удалится :)

Цитата:

Сообщение от x-yuri
в результате код будет выглядеть как-то так:

И вместо одного прохода два.

x-yuri 02.08.2010 15:10

Цитата:

Сообщение от Kolyaj
Но т.к. элемент массива это такое же свойство, он таки удалится

var a = [1,2,3];
delete a[1];
alert(a);

удалится, но в результате получим разреженный массив, т.е. будут пропуски в элементах массива. Зачем делать проверки на существование элемента массива, если их можно не делать? Обычно так делают, потому что не знают, как сделать по-другому. Или когда нужен ассоциативный массив. Когда нужен разряженный массив... ничего в голову не приходит

Цитата:

Сообщение от Kolyaj
И вместо одного прохода два.

да, и что? Если выясниться, что это оказывает заметное влияние на производительность, всегда можно исправить

KOLANICH 02.08.2010 15:15

не пашед с методом filter
пишет, что его не существует

как преобразовать объект в массив?


пс как выяснилось , массивов вообще нет, одни объекты (создал массив через new Array, взял тип - объект)

Kolyaj 02.08.2010 15:16

Цитата:

Сообщение от x-yuri
Зачем делать проверки на существование элемента массива, если их можно не делать?

Ну когда как лучше. Если проверка на существование элемента дешевле перестановки кучи элементов, чтобы убрать дырку? Ты же в своём примере не удаляешь элементы из массива, а создаёшь новый.

Kolyaj 02.08.2010 15:17

Цитата:

Сообщение от KOLANICH
не пашед с методом filter

Метод filter есть во всех браузерах, кроме IE.

Цитата:

Сообщение от KOLANICH
пс как выяснилось , массивов вообще нет, одни объекты (создал массив через new Array, взял тип - объект)

Массивы -- это объекты, порождаемые конструктором Array. Они называются массивами. Они есть.

x-yuri 02.08.2010 15:22

Цитата:

Сообщение от KOLANICH
не пашед с методом filter

ты мое сообщение читал?
Цитата:

Сообщение от x-yuri
В-третьих, массивы фильтруются с помощью метода filter. Здесь сказано, как использовать его кроссбраузерно.

Цитата:

Сообщение от KOLANICH
пс как выяснилось , массивов вообще нет, одни объекты (создал массив через new Array, взял тип - объект)

alert([] instanceof Array);
alert({} instanceof Array);

KOLANICH 02.08.2010 16:27

Цитата:

Сообщение от x-yuri (Сообщение 65922)
Для копирования массивов можно использовать следующую функцию (в частности работает при копировании из HTMLCollection и arguments)
function $A(iterable){
	if (iterable.item){
		var l = iterable.length, array = new Array(l);
		while (l--) array[l] = iterable[l];
		return array;
	}
	return Array.prototype.slice.call(iterable);
};

в результате код будет выглядеть как-то так:
var divs = document.getElementsByTagName('div');
divs = $A(divs).filter(function(el){
    return el.style.display != 'none' &&
        el.type=="hidden" &&
        el.style.zIndex<=-3;
});

то есть надо вручную копировать?
тогда проще фильтрацию сразу в копирование вставить

x-yuri 02.08.2010 16:33

Цитата:

Сообщение от Kolyaj
Ну когда как лучше. Если проверка на существование элемента дешевле перестановки кучи элементов, чтобы убрать дырку?

как я и думал, в специфических случаях

Цитата:

Сообщение от KOLANICH
тогда проще фильтрацию сразу в копирование вставить

ну если тебе проще - вставляй

Kolyaj 03.08.2010 18:04

Цитата:

Сообщение от x-yuri
var divs = document.getElementsByTagName('div');
divs = $A(divs).filter(function(el){
return el.style.display != 'none' &&
el.type=="hidden" &&
el.style.zIndex<=-3;
});

Кстати, лучше так
var divs = document.getElementsByTagName('div');
divs = [].filter.call(divs, function(el){
    return el.style.display != 'none' &&
        el.type=="hidden" &&
        el.style.zIndex<=-3;
});


Тогда будет один проход.

рони 04.08.2010 11:45

может так ?
for (var divs = document.getElementsByTagName("div"), c = [], i = 0; i < divs.length; i++)
divs[i].style.display != "none" && divs[i].type != "hidden" && divs[i].style.zIndex > -3 && c.push(divs[i]);
divs = c;

Kolyaj 04.08.2010 11:56

рони,
это то же самое, только вместо filter руками цикл записывается.

KOLANICH 04.08.2010 15:38

function fakeCheck(els){
		var checked=[];
		for(var i=0;i<els.length;i++){
			if(els[i].style.display!='none'&&els[i].type!="hidden"&&els[i].style.zIndex>=0){
				checked.push(els[i]);
				
			}
		}
		return checked;
	}

у меня так

x-yuri 04.08.2010 21:44

рони, тогда давай уж так, зачем на полпути останавливаться? (алгоритм, кстати, тоже немного поменял)
for(var a=document.getElementsByTagName("div"),b=[],i=a.length-1;i>=0;i--)a[i].style.display!="none"&&a[i].type!="hidden"&&a[i].style.zIndex>-3&&(b[i]=a[i]);

рони 04.08.2010 22:14

x-yuri,
гмм массив с дырками от которых вроде уходили ? или я чего не понял?

x-yuri 05.08.2010 00:21

а, провтыкал, забыл, что там фильтруются элементы. Будем считать, что я хотел что-то такое написать
for(var a=document.getElementsByTagName("div"),b=[],i=0,c=a.length;i<c;i++)a[i].style.display!="none"&&a[i].type!="hidden"&&a[i].style.zIndex>-3&&b.push(a[i]);

хотя... массив с дырками... звучит заманчиво... нам ли, оптимизатором, не привыкать спотыкаться об эти дырки? Зато цикл быстрее работать стал, м? ;)


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