• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

JS: Array mittels split erzeugen - Bug??

nietaL

NGBler

Registriert
8 Sep. 2013
Beiträge
231
Ort
Exilgullianer
Hey Leute,

ich habe folgende Funktion in JS geschrieben.

[src=javascript]
function los()
{
// var fruits_liste = 'Banana;Orange;Apple;Mango;'; // A --> 5
// var fruits_liste = ';'; // B --> 2
var fruits_liste = ''; // C --> 1 ???


var fruits_array = fruits_liste.split(";");

alert (fruits_array.length);
}
[/src]

Aus einer Liste, die ihre Elemente durch ein Semikolon trennt, soll ein Array gezaubert werden. Draufhin interessiert mich die Anzahl der Elemente im Array. Dass bei Variante A und B jeweils eins zu viel angezeigt wird, kann ich aufgrund des letztlichen Semikolons noch nachvollziehen und lässt sich allgemein durch alert (fruits_array.length-1); lösen. Wenn aber nun die Liste leer ist, also weder Elemente noch Trennzeichen vorhanden sind, geht mein Menschenverstand davon aus, dass leer=0 sein sollte. Er zeigt mir aber bei alert (fruits_array.length); eine 1 an.

Warum? :confused:
 

werner

Suchtspielmacher (ehm.)

Registriert
20 Juli 2014
Beiträge
743
Ort
Mannheim
Gib dir doch mal das nicht leere Array aus. Vermutlich mit einem leeren Eintrag "".

Wenn du "a".split(";") machen würdest, hättest du am Ende ein Array mit einem Eintrag: ["a"].
Wenn du "".split(";") machst, genau dieselbe Arraylänge, nur eben [""].

Klar?
 

nietaL

NGBler

Registriert
8 Sep. 2013
Beiträge
231
Ort
Exilgullianer
  • Thread Starter Thread Starter
  • #3
Sonderlich logisch finde ich das nicht. Ein Array mit keinem Element ist für mich dasselbe wie eine Array mit einem Element ohne Zeichen. 1x0 und 0x1 ist schließlich in der Mathematik auch dasselbe. Ist das in allen Programmiersprachen so?

if (fruits_array[0] == '') {fruits_array = [];}

Wäre das dann legitim?
 

Jester

★★★★☆ (Kasparski)

Registriert
1 Dez. 2014
Beiträge
6.066
Ort
Code Azure
Das ist völlig logisch :) In der Informatik gibt es als Datentyp-Unterart das sog. "leere Wort", also eine als String deklarierte Variable ohne Inhalt. Obwohl leer, stellt dieser leere Wert eine Information dar - ähnlich einer 0 als Zahl.

Split hat eine Eigenart: bei nicht erfolgtem Teilen wird der Ausgangsstring zurückgegeben. Wenn Du also '' anhand von ";" splittest, kann nicht gesplittet werden und '' wird zurückgegeben.

In Deinem Fall macht eine Bereiningung Sinn - hier ein schnell zusamengeschustertes Beispiel:

[src=javascript]function los(){
// var fruits_liste = 'Banana;Orange;Apple;Mango;'; // A --> 5
// var fruits_liste = ';'; // B --> 2
var fruits_liste = ''; // C --> 1 ???


if(fruits_liste != ''){
if(fruits_liste.substr(-1,1) == ';'){
fruits_liste = fruits_liste.substr(0,fruits_liste.length -1)
}

var fruits_array = fruits_liste.split(';');

if(typeof fruits_array === 'object'){
alert (fruits_array.length);
}
}
else{
alert ('Keine Werte in CSV, kein Array');
}
}[/src]

Übrigens wäre es besser, anstatt den Ausgangsstring zu bereinigen, das Schreiben entsprechend anzupassen, also nach dem letzten Wert kein Semikolon zu schreiben.

Gruß, J.
 
Zuletzt bearbeitet:

werner

Suchtspielmacher (ehm.)

Registriert
20 Juli 2014
Beiträge
743
Ort
Mannheim
Ich schätze, .split() generiert immer ein Array und überprüft vorher nicht, ob der Eintrag leer ist. Wenn man nämlich auf das gesplittete Array an Position [0] zugreifen möchte, ist es nie undefined, egal ob leerer String oder nicht.

Deine if-Abfrage sollte so funktionieren. Allerdings würde ich schon vorher prüfen, ob der Inputstring leer ist, und dann erst gar nicht splitten.
 

nietaL

NGBler

Registriert
8 Sep. 2013
Beiträge
231
Ort
Exilgullianer
  • Thread Starter Thread Starter
  • #6
vielen Dank. Ich bin überzeugt. Habe es jetzt so hinbekommen.

Aber hier habe ich noch so ein Phänomen. Diesmal habe ich bestimmt einen BUG in JS entdeckt :D
Warum ergibt dieses Skript die Antwort 'Ananas'? Hat es auch etwas mit leeren Arrays zu tun?

[src=javascript]
function los(BS)
{
obst = new Array('Apfel', 'Ananas', 'Avocado');

for(var i=0; i < obst.length; i++)
{
if(obst.substr(0,1).match(BS))
{
obst.splice(i,1);
}
}
alert (obst.join(', '));
}
[/src]
[src=html4strict]
<input type="button" onClick="los('A');" value="looooos">

[/src]

Wenn ich Birne zum Array hinzufüge, kommt 'Birne, Ananas'... Als begänne Ananas nicht mit A.
 

BurnerR

Bot #0384479

Registriert
20 Juli 2013
Beiträge
5.508
Über eine Datenstruktur zu iterieren, und dann in der Schleife die Anzahl der Elemente zu ändern o.ä. ist in der Regel böse, du bist jetzt auch darüber gestolpert.
Überleg dir einfach mal, wie das Array nach dem ersten Durchlauf in der for-Schleife aussieht und was dann genau im zweiten Durchlauf gemacht wird.
 

nietaL

NGBler

Registriert
8 Sep. 2013
Beiträge
231
Ort
Exilgullianer
  • Thread Starter Thread Starter
  • #8
ach verdammt. klar! Das Array verändert sich ja mit jedem Durchlauf. :m

Gibt es eine eine elegante und einfache Möglichkeit, mehrere Elemente zu löschen?
 

BurnerR

Bot #0384479

Registriert
20 Juli 2013
Beiträge
5.508
Du wirst vermutlich eine Kopie des Arrays erzeugen wollen und über dieses dann iterieren.
 

werner

Suchtspielmacher (ehm.)

Registriert
20 Juli 2014
Beiträge
743
Ort
Mannheim
Speicher doch die Werte, die NICHT gelöscht werden, in einem neuen Array und gibst das zurück?
 

BurnerR

Bot #0384479

Registriert
20 Juli 2013
Beiträge
5.508
Ja, so herum ist es vermutlich netter. Jedenfalls musst du mit zwei Arrays arbeiten.
 

nietaL

NGBler

Registriert
8 Sep. 2013
Beiträge
231
Ort
Exilgullianer
  • Thread Starter Thread Starter
  • #12
sehr gute Idee. habe so ein temporäres array angelegt und das ursprüngliche dann durch jenes ersetzen lassen. wieder etwas gelernt. vielen dank. :coffee:
 

virtus

Gehasst

Registriert
24 Apr. 2015
Beiträge
1.689
Ort
AUF DEM MOND
Hey Leute,

ich habe folgende Funktion in JS geschrieben.

[src=javascript]
function los()
{
// var fruits_liste = 'Banana;Orange;Apple;Mango;'; // A --> 5
// var fruits_liste = ';'; // B --> 2
var fruits_liste = ''; // C --> 1 ???


var fruits_array = fruits_liste.split(";");

alert (fruits_array.length);
}
[/src]

Aus einer Liste, die ihre Elemente durch ein Semikolon trennt, soll ein Array gezaubert werden. Draufhin interessiert mich die Anzahl der Elemente im Array. Dass bei Variante A und B jeweils eins zu viel angezeigt wird, kann ich aufgrund des letztlichen Semikolons noch nachvollziehen und lässt sich allgemein durch alert (fruits_array.length-1); lösen. Wenn aber nun die Liste leer ist, also weder Elemente noch Trennzeichen vorhanden sind, geht mein Menschenverstand davon aus, dass leer=0 sein sollte. Er zeigt mir aber bei alert (fruits_array.length); eine 1 an.

Warum? :confused:

Nein, dass ist alles vollkommen richtig, so wie es passiert.
Die Zerlegung (split) findet um das Trennzeichen herum statt.
In der Informatik verwendet man meist das sog. leere Wort, um zum verdeutlichen, was passiert.
'' entspricht dem leeren Wort, also einem Wort der Länge 0.

[src=javascript]var fruits_liste = 'Banana;Orange;Apple;Mango;';
var fruits_array = fruits_liste.split(';'); // ist array('Banana', 'Orange', 'Apple', 'Mango', '');

var fruits_liste = ';';
var fruits_array = fruits_liste.split(';'); // ist array('', '');

var fruits_liste = '';
var fruits_array = fruits_liste.split(';'); // ist array('');[/src]

Im Fall 1 besteht der String aus: Banana;Orange;Apple;Mango;<LeeresWort>
Im Fall 2 besteht der String aus: <LeeresWort>;<LeeresWort>
Im Fall 3 besteht der String aus: <LeeresWort>
Fall 1 kann also in Banana, Orange, Apple, Mango und <LeeresWort> aufgesplittet werden.
Fall 2 kann also in <LeeresWort> und <LeeresWort> aufgesplittet werden.
Fall 3 kann nicht aufgetrennt werden, das einzige Element ist also <Leeres Wort>.

--- [2016-06-06 14:46 CEST] Automatisch zusammengeführter Beitrag ---

Sonderlich logisch finde ich das nicht. Ein Array mit keinem Element ist für mich dasselbe wie eine Array mit einem Element ohne Zeichen.
Nein, ein Array ohne Elemente ist
var emptyArray = []; bzw. var emptyArray = new Array();
Ein Array mit einem Element mit 0 Zeichen ist var emptyArray = ['']; bzw. var emptyArray = new Array('');
Und nein, das ist nicht gleich. Ein Array ist eine Sammlung von Zeigern. Wobei jeder Zeiger auf einen Wert zeigen kann.
Ein leeres Array enthält 0 Zeiger. Ein Array mit einem Element enthält zwangsweise einen Zeiger. Dieser kann, muss jedoch nicht, auf ein leeres Wort zeigen.

Natürlich ist für dich ein leeres Stück Papier im Ergebnis gleich einem Stück Papier auf dem kein Zeichen drauf geschrieben ist, aber in der Informatik gibt es da eben doch Unterschiede. Bei einem Array kannst du an einen Setzkasten denken, in den du kleine Zettel mit Verweisen legst, auf denen steht, wo sich der Gegenstand befindet.
Ein leeres Array ist ein Setzkasten, in dem sich kein Zettel befindet. Ein Array mit einem Element, welches auf das leere Wort verweist, ist wie ein Setzkasten mit einem Zettel auf dem nichts drauf steht.

Ist das in allen Programmiersprachen so?
Ja. Wie gesagt handelt es sich dabei um das leere Wort. Das leere Wort musst du unbedingt von "nichts" unterscheiden.
'' ist ein leerer String, was du willst ist null.

[src=javascript]if (fruits_array[0] == '') {fruits_array = [];}[/src]
Nein, pauschal kannst du das nicht machen:
var fruits_string = ";Affe;Bär"; // ['', 'Affe', 'Bär']
 

Warbyrd

Neu angemeldet

Registriert
24 Juli 2014
Beiträge
17
Ein weiterer Vorschlag wäre z.B. zu gucken
1. ob ein Semikolon schon am Anfang steht
2. ob 2 Semikolons hintereinander vorkommen
3. ob ein Semikolon am Ende des Strings steht
4. ob ein "&" im String vorkommt, was darauf hinweisen kann, dass es codierte Sonderzeichen im String gibt wie z.B. " " oder "ü", "ä" etc. was Probleme beim Splitten verursachen könnte.
[src=javascript]
if ((fruits_list.indexOf(";") == 0) || (fruits_list.indexOf(";;") > -1) || (fruits_list.lastIndexOf(";") == fruits_list.length-1) || (fruits_list.indexOf("&") > -1)){
alert("fruits_list enthält leere/Fehlerhafte Einträge");

fruits_list = fruits_list.replace(";;",";");
fruits_list = fruits_list.replace("/;$/g","");
fruits_list = fruits_list.replace("/^;/g","");

// hier werden 2 durchläufe an bereinigungen durchgeführt, damit auch strings wie "&nbsp;" aus der fruits_list gefiltert werden.

var ta = document.createElement("textarea");
ta.innerHTML = fruits_list ;

var ta2 = document.createElement("textarea");
ta2.innerHTML = ta.value;

fruits_list = ta2.value;
fruits_list = fruits_list .replace(";;",";");
fruits_list = fruits_list .replace(/;$/,"");
fruits_list = fruits_list .replace(/^;/,"");

} else {
var fruits_array = fruits_liste.split(";");
}
[/src]
;)
 
Zuletzt bearbeitet:

nietaL

NGBler

Registriert
8 Sep. 2013
Beiträge
231
Ort
Exilgullianer
  • Thread Starter Thread Starter
  • #15
Oh, vielen dank noch einmal für die weiteren ausführlichen Kommentare. Ich habe ein Einsehen, dass ein leeres Papier nicht dasselbe ist wie kein Papier :T
 
Oben