Crash beim Durchlaufen eines Arrays
IneX
- javascript
Ich habe eine Funktion geschrieben, die das Ziel hat ein bestehendes Array nach einem übergebenen Wert zu druchsuchen. Es sind alles Integer, also Zahlen.
Das Problem ist aber, dass das Script eine Endlosschleife generiert, sofern ich eine } else { .... Anweisung für die Ausgabe des Resultats anwende. Hier der Code:
function search_array(from_array,search_int)
{
var arr = from_array;
var obj = search_int;
if (obj != ""){
for (i = 0; i < arr.length; i++){
if (arr[i] != obj){
return 1;
} else {
return -1;
}
}
}
}
Sobald das Script auf einen passenden Wert trifft, stürzt es ab. (Zur Info: wenn ein Wert im Array enthalten ist, ist es schlecht. Deshalb die Prüfung ob ein Wert NICHT im Array existiert. Stichwort "Blacklist")
Ich habe schon einige Varianten versucht, z.B. anstatt ein return eine globale Variable mit 1 oder -1 zu beschreiben und auf diese zuzugreiffen; mit dem gleichen Resultat.
Hat jemand eine Idee, woran das liegt bzw. wo ich einen Fehler mache?
Hallo IneX,
ich glaube, die Schleife wird nur einmal durchlaufen und je nach Wert im Array an Stelle 0 wird die Funktion mit Rückgabe 1 oder -1 beendet. Es wird also nur das erste Element überprüft. Lass den "else-Zweig" in der Schleife einfach weg und setze hinter die Schleife ein "return -1". Wird das Element gefunden, werden die Schleife und die Funktion mit return 1 beendet, wird das Element nicht gefunden, läuft die Schleife bis zum Schluss und die Funktion wird dann mit return -1 beendet.
Gruß, Jürgen
Lass den "else-Zweig" in der Schleife einfach weg und setze hinter die Schleife ein "return -1". Wird das Element gefunden, werden die Schleife und die Funktion mit return 1 beendet, wird das Element nicht gefunden, läuft die Schleife bis zum Schluss und die Funktion wird dann mit return -1 beendet.
Hi Jürgen
Danke für deine Hilfe. Wenn ich Else weglasse funktioniert es trotzdem nicht. IE meldet jeweils, dass das Script eine "Verzögerung im Internet Explorer" hervorruft und ob ich das Script weiterhin ausführen möchte oder nicht (wobei auch gleich die Frage von Struppi beantwortet wäre.
Hallo IneX,
dann zeig mal deine aktuelle Version.
Gruß, Jürgen
dann zeig mal deine aktuelle Version.
function search_array(from_arr,search_int)
{ /* FÜHRT ZU EINER UEBERLASTUNG DES SCRIPTS */
var arr = from_arr;
if (search_int){
for (var i = 0; i < arr.length; i++){
if (arr[i] == search_int){
return 1;
}
return -1;
}
}
}
Hallo IneX,
function search_array(from_arr,search_int)
{ /* FÜHRT ZU EINER UEBERLASTUNG DES SCRIPTS */
var arr = from_arr;
warum das Umspeichern?
if (search_int){
for (var i = 0; i < arr.length; i++){
if (arr[i] == search_int){
return 1;
}
return -1;
}
}
}
Gruß, Jürgen
function search_array(from_arr,search_int)
{ /* FÜHRT ZU EINER UEBERLASTUNG DES SCRIPTS */
Aber nicht wegen dieser Funktion.
if (search_int){
for (var i = 0; i < arr.length; i++){
if (arr[i] == search_int){
return 1;
}
return -1;
}
Die Schleife läuft, wie dir Jürgend auch schon gesagt hat, immer noch nur einmal durch.
Also ich würde das ganze soweiso mit einem Prototypen machen, dann kannst du das auf alle deine Arrays anwenden.
Array.prototype.isIn = function(val) {
if(val) {
for(var i = 0; i < this.length; i++) {
if(this[i] == val) return i;
}
}
return -1;
};
var test = [1,2,3,4,5];
alert( test.isIn(4) )
alert( test.isIn(0) )
Struppi.
function search_array(from_array,search_int)
{
var arr = from_array;
var obj = search_int;
Die Variabel obj dürfte nicht nötig sein.
if (obj != ""){
hier kannst du schreiben
if (!obj){
for (i = 0; i < arr.length; i++){
Das ist schlecht!
Globale Schleifenvairabeln solltest du immer vermeiden
for (var i = 0; i < arr.length; i++){
if (arr[i] != obj){
return 1;
} else {
return -1;
}
D.h. du willst die Schleife nur einmal durchlaufen lassen?
Sobald das Script auf einen passenden Wert trifft, stürzt es ab.
Was heiß abstürzen? Bluescreen?
bekommst du keine Fehlermeldung?
Struppi.
Hi,
if (obj != ""){
hier kannst du schreiben
if (!obj){
Kleine Korrektur:
if(obj){
mfG,
steckl
gruss IneX,
Ich habe eine Funktion geschrieben, die das Ziel hat,
ein bestehendes Array nach einem übergebenen Wert zu
druchsuchen. Es sind alles Integer, also Zahlen.Das Problem ist aber, dass das Script eine Endlosschleife
generiert ...
...
Sobald das Script auf einen passenden Wert trifft,
stürzt es ab. (Zur Info: wenn ein Wert im Array
enthalten ist, ist es schlecht. Deshalb die Prüfung
ob ein Wert NICHT im Array existiert. Stichwort "Blacklist")
... Hier der Code:
function search_array(from_array,search_int)
{
var arr = from_array;
var obj = search_int;
~~~javascript
/*
[from_array] und [search_int] liegen bereits im
*wirkungsbereich* Deiner funktion und muessen
daher nicht nochmal referenziert werden.
*/
if (obj != ""){
[code lang=javascript] /*
auf [""], [0] und [false] immer strikt (!== bzw. ===)
pruefen, denn es gilt:
(("" == 0) === ("" == false) === (0 == false)) === true
*/
> ~~~javascript
for (i = 0; i < arr.length; i++){
> if (arr[i] != obj){ // siehe oben und [*1]
> return 1;
> } else {
> return -1;
> }
> }
> }
> }
[*1] Dein code erzwingt ueber "return
" bei (i === 0)
den sofortigen ausstieg aus der schleife ...
... persoenlich halte ich das fuer schlechten stil und
plaediere hiermit fuer den einsatz des stiefmuetterlich
behandelten "break
".
unter beruecksichtigung moeglicher zukuenftiger array-
methoden koenntest Du Deine methode auch [indexOf]
nennen.
und damit diese nicht allein im globalen namensraum
abhaengen muss, darfst Du diese ruhig sowohl *statisch*
als auch *prototypisch* an den [[Array]]
-konstruktor tackern.
siehe dazu auch:
[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:indexOf]
hier ein moeglicher statischer entwurf ...
// [[link:http://www.pseliger.de/jsExtendedApi/jsApi.Array.mozGenerics.dev.js]]
//if (typeof Array.indexOf != "function") {
Array.indexOf = (function (obj, objLookingFor, idx) {
//var k, i = -1, l = ((typeof obj.length == "number") ? (obj.length) : (0));
var k, i = -1, l = (((obj instanceof Array) || ((typeof obj.length == "number") && ((typeof obj.item == "function") || (typeof obj.item == "object") || (typeof obj.item == "string") || (obj instanceof window.NodeList) || (obj instanceof window.HTMLCollection)))) ? (obj.length) : (0));
//[[link:http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:indexOf#Parameters]]
idx = ((idx && isNaN(Number(idx))) ? (parseInt(Number(idx), 10)) : (0));
idx = ((idx < 0) ? (Math.max(0,(l + idx))) : (idx));
for (k=idx; k<l; ++k) {
//if (obj[k] === objLookingFor) {
if ((obj[k] || obj.item(k)) === objLookingFor) {
i = k;
break;
}
}
return i;
});
//}
... und hier das prototypische gegenstück ...
// [[link:http://www.pseliger.de/jsExtendedApi/jsApi.Array.mozExtensions.dev.js]]
if (typeof Array.prototype.indexOf != "function") {
Array.prototype.indexOf = (function (obj, idx) {
//[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:indexOf#Parameters]
idx = ((idx && isNaN(Number(idx))) ? (parseInt(Number(idx), 10)) : (0));
idx = ((idx < 0) ? (Math.max(0,(this.length + idx))) : (idx));
var k, i = -1;
for (k=idx; k<this.length; ++k) {
if (this[k] === obj) {
i = k;
break;
}
}
return i;
});
}
... darauf liessen sich dann auch noch die passenden eigenen [contains]
-methoden pfropfen:
// [http://www.pseliger.de/jsExtendedApi/jsApi.Array.mozGenerics.dev.js]
//if (typeof Array.contains != "function") {
Array.contains = (function (obj, objLookingFor) {
return (Array.indexOf(obj, objLookingFor) >= 0);
});
//}
// [http://www.pseliger.de/jsExtendedApi/jsApi.Array.mozExtensions.dev.js]
if (typeof Array.prototype.contains != "function") {
Array.prototype.contains = (function (obj) {
return (this.indexOf(obj) >= 0);
});
}
so long - peterS. - pseliger@gmx.net
Hi Peter
Danke für deinen Input zu meinem Problem. Leider übersteigen deine Beispiele meine JavaScript Kenntnisse, weshalb ich die Funktionen nicht an mein Script adaptieren soll; aber vorweg: es kann doch nicht sein, dass es so kompliziert ist, herauszufinden ob ein Wert in einem Array vorkommt oder nicht?? Das sollte doch mit einem simplen durchlaufen des Arrays, im Ansatz wie in meinem Post zu diesem Problem, zu lösen sein??
Gruss
IneX
[*1] Dein code erzwingt ueber "
return
" bei (i === 0)
den sofortigen ausstieg aus der schleife ...... persoenlich halte ich das fuer schlechten stil und
plaediere hiermit fuer den einsatz des stiefmuetterlich
behandelten "break
".unter beruecksichtigung moeglicher zukuenftiger array-
methoden koenntest Du Deine methode auch[indexOf]
nennen.
und damit diese nicht allein im globalen namensraum
abhaengen muss, darfst Du diese ruhig sowohl *statisch*
als auch *prototypisch* an den[[Array]]
-konstruktor tackern.siehe dazu auch:
[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:indexOf]
hier ein moeglicher statischer entwurf ...
// [[link:http://www.pseliger.de/jsExtendedApi/jsApi.Array.mozGenerics.dev.js]]
//if (typeof Array.indexOf != "function") {
Array.indexOf = (function (obj, objLookingFor, idx) {
//var k, i = -1, l = ((typeof obj.length == "number") ? (obj.length) : (0));
var k, i = -1, l = (((obj instanceof Array) || ((typeof obj.length == "number") && ((typeof obj.item == "function") || (typeof obj.item == "object") || (typeof obj.item == "string") || (obj instanceof window.NodeList) || (obj instanceof window.HTMLCollection)))) ? (obj.length) : (0));//[[link:http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:indexOf#Parameters]]
idx = ((idx && isNaN(Number(idx))) ? (parseInt(Number(idx), 10)) : (0));
idx = ((idx < 0) ? (Math.max(0,(l + idx))) : (idx));for (k=idx; k<l; ++k) {
//if (obj[k] === objLookingFor) {
if ((obj[k] || obj.item(k)) === objLookingFor) {
i = k;
break;
}
}
return i;
});
//}
>
>
> ... und hier das prototypische gegenstück ...
>
>
> ~~~javascript
// [[link:http://www.pseliger.de/jsExtendedApi/jsApi.Array.mozExtensions.dev.js]]
> if (typeof Array.prototype.indexOf != "function") {
>
> Array.prototype.indexOf = (function (obj, idx) {
>
> //[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:indexOf#Parameters]
> idx = ((idx && isNaN(Number(idx))) ? (parseInt(Number(idx), 10)) : (0));
> idx = ((idx < 0) ? (Math.max(0,(this.length + idx))) : (idx));
> var k, i = -1;
> for (k=idx; k<this.length; ++k) {
> if (this[k] === obj) {
> i = k;
> break;
> }
> }
> return i;
> });
> }
... darauf liessen sich dann auch noch die passenden eigenen
[contains]
-methoden pfropfen:
// [http://www.pseliger.de/jsExtendedApi/jsApi.Array.mozGenerics.dev.js]
//if (typeof Array.contains != "function") {
Array.contains = (function (obj, objLookingFor) {
return (Array.indexOf(obj, objLookingFor) >= 0);
});
//}
>
>
> ~~~javascript
// [http://www.pseliger.de/jsExtendedApi/jsApi.Array.mozExtensions.dev.js]
> if (typeof Array.prototype.contains != "function") {
>
> Array.prototype.contains = (function (obj) {
>
> return (this.indexOf(obj) >= 0);
> });
> }
so long - peterS. - pseliger@gmx.net
...weshalb ich die Funktionen nicht an mein Script adaptieren soll;
nicht "soll", sondern "kann" ;-)
.. es kann doch nicht sein, dass es so kompliziert ist, herauszufinden ob ein Wert in einem Array vorkommt oder nicht?? Das sollte doch mit einem simplen durchlaufen des Arrays, im Ansatz wie in meinem Post zu diesem Problem, zu lösen sein??
Ist es auch und ich hab dir auch bereits ein paar Sachen gezeigt wo bei deinem Code die Probleme sind.
Struppi.
hallo again IneX
... aber vorweg: es kann doch nicht sein, dass es so kompliziert ist,
herauszufinden ob ein Wert in einem Array vorkommt oder nicht??
ist es auch nicht, und Du hast sowohl von Jürgen als auch von Struppi
und mir jeweils als antwort erhalten, dass Deine schleife niemals das
komplette array durchlaeuft, da Du diese schon nach dem ersten vergleich
ueber "return
" verlaesst.
... haendchen halten ist zwar nicht so mein ding, aber wegen ...
Hi Peter
Danke für deinen Input zu meinem Problem. Leider übersteigen deine
Beispiele meine JavaScript Kenntnisse, ...
... hol' ich Dich mal direkt bei Deinem problem ab:
Du moechtest jeweils das komplette array iterieren, denn erst nach dem
letzten negativ ausfallenden vergleich - letzter array-eintrags versus
vorgegebener vergleichswert - kannst Du Dir sicher sein, dass ebendiese
vorgabe nicht im array vorkommt. dafuer darfst Du die iteration sofort
abbrechen, sobald ein vergleich positiv ausfaellt.
//function search_array(from_array,search_int) {
function arrayContains(arr, obj) { // Du suchst ein objekt in einem array.
var i, len = arr.length, isInArray = false; // default rueckgabewert [1].
for (i=0; i<len; ++i) { // durchlaeuft die schleife ...[2]...
if (arr[i] === obj) { // [1] strikte pruefung auf *vorhandensein*.
isInArray = true; // [1] boolscher default-rueckgabewert wird geaendert.
break; // [2].., und bricht den kompletten zyklus beim ersten treffer ab.
}
}
return isInArray; // [1] [false], wenn kein einziger vergleich etwas hergab.
}
wie unschwer zu erkennen ist, gibt es im kern dieser funktionalitaet -
"wie wird geprueft, wann und auf welche art wird die pruefende iteration
abgebrochen" - eine grosse naehe zu den anderen von mir vorgeschlagenen
universelleren loesungen.
guten stil bewiese man jetzt noch, wenn man das argument [arr] einer
typpruefung unterzoege.
so long - peterS. - pseliger@gmx.net