Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Semikolons aus Daten entfernen

24 views
Skip to first unread message

Wolfgang Wolf

unread,
Sep 26, 2019, 5:44:23 AM9/26/19
to
Hallo,

habe folgendes Problem: Möchte aus Daten eine csv-Datei erstellen. Das
funktioniert bereits. Leider sind in einigen Attributen Semikolons
enthalten, die natürlich die Ausgabe verstümmeln. Ich würde gerne vor
dem Export alle Semikolons durch ein anderes Zeichen ersetzen.

Nun könnte ich mit der Holzhammermethode vorgehen, also eine Schleife
über alle Array-Elemente und die Attribute jedes Objekts einzeln bearbeiten.

Geht das vielleicht auch komfortabler? So was wie: Alle Daten in einen
(großen) String serialisieren, eine globale Ersetzung vornehmen und aus
dem String wieder die Objekte und das Array herstellen? Ggf. nur die
Objekte einzeln serialisieren, bearbeiten und wiederherstellen?

Erwarte natürlich keine fertige Lösung, mir würden ein paar
"Verkehrsschilder" schon reichen.

Meine Daten sehen in etwa so aus:

data = [
{
artnr: "ACW0219-0.50-0",
benennung: "Draht;sw;0,5mm²;40°C...150°C",
​​ bestand: "85,20"
},{
artnr: "ACW0219-1.50-0",
benennung: "Draht;sw;1,5mm²;40°C...150°C",
​​ bestand: "100,10"
}
]

Die Ersetzungen müsste ich "nur" in bestimmten Feldern vornehmen, was
natürlich für die Holzhammermethode spricht. Andererseits wäre mir eine
universelle Funktion, bei der ich alle Felder anschaue, auch ganz recht,
damit ich dieses Ding nie wieder anfassen muss.

Danke euch für jeden Wink!

Schönen Gruß
W. Wolf

Wolfgang Wolf

unread,
Sep 26, 2019, 7:40:21 AM9/26/19
to
Am 26.09.2019 um 11:44 schrieb Wolfgang Wolf:
> Hallo,
>
> habe folgendes Problem: Möchte aus Daten eine csv-Datei erstellen. Das
> funktioniert bereits. Leider sind in einigen Attributen Semikolons
> enthalten, die natürlich die Ausgabe verstümmeln. Ich würde gerne vor
> dem Export alle Semikolons durch ein anderes Zeichen ersetzen.

Ok, habe das jetzt erst mal auf die Schnelle so gelöst:

for (var i = 0; i < data.length; i++) {
for (var prop in data[i]) {
var dProp = data[i][prop];
if (typeof dProp == "string") {
data[i][prop] = dProp.replace(/;/g,",");
}
}
}


Bessere Lösungen sind natürlich willkommen.

Gruß
W. Wolf

Claus Reibenstein

unread,
Sep 26, 2019, 8:44:22 AM9/26/19
to
Wolfgang Wolf schrieb am 26.09.2019 um 11:44:

> habe folgendes Problem: Möchte aus Daten eine csv-Datei erstellen. Das
> funktioniert bereits. Leider sind in einigen Attributen Semikolons
> enthalten, die natürlich die Ausgabe verstümmeln.

Aber nur dann, wenn Du Semikolon als Trennzeichen benutzt _und_ der
Exporter kaputt ist.

> Ich würde gerne vor
> dem Export alle Semikolons durch ein anderes Zeichen ersetzen.

Sinnvoller wäre es, den Exporter zu reparieren.

Alternativ könntest Du auch ein anderes Zeichen als Trenner verwenden.
Tipp: Das "C" in CSV steht für "Comma" ;-)

Gruß
Claus

Wolfgang Wolf

unread,
Sep 26, 2019, 9:57:53 AM9/26/19
to
Am 26.09.2019 um 14:44 schrieb Claus Reibenstein:

> Aber nur dann, wenn Du Semikolon als Trennzeichen benutzt _und_ der
> Exporter kaputt ist.

Der "Exporter" ist Teil eines Frameworks (SenchaExt). Da pfuscht man
nicht gerne drin rum. Bis auf diese "Kleinigkeit" tut's ja. So kann er
z.B. ganz vernünftig mit den Gänsefüßchen (das kommt bei uns immer
wieder mal vor, z.B. als Zeichen für Zoll) umgehen. Nur bei dem
Semikolon bockt er.

>
> Sinnvoller wäre es, den Exporter zu reparieren.
>
> Alternativ könntest Du auch ein anderes Zeichen als Trenner verwenden.
> Tipp: Das "C" in CSV steht für "Comma" ;-)

Warum? Im Semikolon befindet sich doch ein Komma ;-)

Nun ja, inzwischen tut's ja. Der faule Entwickler wollte das halt nur in
einem Einzeiler gelöst haben...

Gruß
W. Wolf

Thomas 'PointedEars' Lahn

unread,
Sep 26, 2019, 12:00:58 PM9/26/19
to
Wolfgang Wolf wrote:

> Am 26.09.2019 um 11:44 schrieb Wolfgang Wolf:
>> Hallo,
>>
>> habe folgendes Problem: Möchte aus Daten eine csv-Datei erstellen. Das
>> funktioniert bereits. Leider sind in einigen Attributen Semikolons
>> enthalten, die natürlich die Ausgabe verstümmeln. Ich würde gerne vor
>> dem Export alle Semikolons durch ein anderes Zeichen ersetzen.
>
> Ok, habe das jetzt erst mal auf die Schnelle so gelöst:
>
> for (var i = 0; i < data.length; i++) {

Ausser wenn der Wert von “data.length” sich ändern kann, solltest Du den
Wert nur ein einziges Mal abfragen.

for (var i = 0, len = data.length; i < len; i++) {

Rückwärts zu iterieren, wenn es auf die Reihenfolge nicht ankommt, ist in
der Regel effizienter, weil der alte Wert der Iterationsvariablen nicht
gespeichert werden muss:

for (var i = data.length; --i;) {

> for (var prop in data[i]) {

Wenn Du for..in-Schleifen verwendest, dann wird über alle aufzählbaren
Eigenschaften des Objekts und seiner Prototypen iteriert. Das solltest Du
vermeiden, denn Du weisst nie, welche Eigenschaften ein Objekt hat.

Über Array-Objekte wird modern so iteriert:

data.forEach(callback);

Über die nicht-vererbten aufzählbaren Eigenschaften eines Objekts so:

Object.keys(obj).forEach(callback);

> var dProp = data[i][prop];

Da “callback” eine Funktion referenzieren muss, brauchst Du dann auf data[i]
nicht mehr separat zuzugreifen: der Wert wird als erstes Argument der
Funktion übergeben und ist somit über den ersten formalen Parameter
verfügbar.

> if (typeof dProp == "string") {

Korrekt. [Ich habe gerade herausgefunden, dass “dProp instanceof String”
nicht (mehr) funktioniert. “Object(dProp) instanceof String” ginge zwar,
aber was soll das? Jetzt kann man nicht (mehr) mit Polymorphie von String
ableiten :-( Ist ähnlich idiotisch wie dass “this” bei Arrow Functions
nicht mehr gesetzt werden kann, so dass der Code unten mit *nur* Arrow
Functions _nicht_ funktioniert.]

Beachte, dass Duck Typing zwar hier auch möglich ist, aber unerwünschte
Ergebnisse haben kann, weil alle nativen Objekte die toString-Methode von
Object.prototype erben.

> data[i][prop] = dProp.replace(/;/g,",");

Sobald Du auf ein Objekt mehrfach zugreifst (hier: das von data[i]
referenzierte Objekt) lohnt es sich die Referenz in einer Variable zu
speichern und dann auf diese Variable zuzugreifen.

> }
> }
> }

Zusammenfassend:

data.forEach(element => {
Object.keys(element).forEach(function (key) {
let value = this[key];

if (typeof value === 'string')
{
this[key] = value.replace(/;/g, ',');
}
}, element);
});

Ein Einzeiler kann es also nicht werden, ausser Du magst Spaghetticode oder
verwendest eine Library.

Ob Du dabei ES 6-Syntax verwendest, ist natürlich Dir überlassen. Mit
Präprozessoren wie Babel.js gibt es aber – ausser der Build-Prozess soll
nicht geändert werden – keinen guten Grund mehr, sie nicht zu verwenden.

Bedenke ausserdem, dass es einen guten Grund gibt, weshalb dort Semikolons
und *nicht* Kommas stehen: In

"Draht;sw;0,5mm²;40°C...150°C"

sind die Daten eindeutig. Bei

"Draht,sw,0,5mm²,40°C...150°C"

(das Ergebnis Deiner Ersetzung) ist das nicht mehr der Fall (ist das Komma
dort ein Feldtrenner oder ist es ein Dezimalkomma?). Widrigenfalls müsstest
Du also zum Beispiel auch das Zahlenformat konvertieren, *bevor* Du den
Feldtrenner konvertierst – sonst geht Information verloren.

> Bessere Lösungen sind natürlich willkommen.

[x] done

--
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

Thomas 'PointedEars' Lahn

unread,
Sep 26, 2019, 12:09:23 PM9/26/19
to
Thomas 'Ingrid' Lahn wrote:

> for (var i = data.length; --i;) {

Das iteriert natürlich nicht über i === 0 (kann aber dann auch hilfreich
sein).

Gemeint war:

for (var i = 0, len = data.length; i < len; --i++) {

> Beachte, dass Duck Typing zwar hier auch möglich ist, aber unerwünschte
> Ergebnisse haben kann, weil alle nativen Objekte die toString-Methode von
> Object.prototype erben.

s/nativen/eingebauten (built-in)/

Wobei ich da gerade nicht sicher bin, ob das noch für alle eingebauten
Objekte gilt oder nur die, die erstmals in ES 3 definiert wurden.

Wolfgang Wolf

unread,
Sep 28, 2019, 4:22:39 AM9/28/19
to
Am 26.09.2019 um 18:00 schrieb Thomas 'PointedEars' Lahn:

> Ausser wenn der Wert von “data.length” sich ändern kann, solltest Du den
> Wert nur ein einziges Mal abfragen.
>
> for (var i = 0, len = data.length; i < len; i++) {

Das leuchtet ein und ist absolut sinnvoll, weil es nichts kostet.
Da wo es darauf ankommt, kann man so die letzte Millisekunde auch noch
einsparen. Auch ich verwende in manchen Programmteilen genau diese
Methodik. In der ersten Klasse lernt man es i.d.R. anders und das sind
so Dinge, bei denen man meistens bleibt. Sicherlich auch dadurch
bedingt, dass es oft keinen für den Anwender spürbaren Effekt hat. Schon
gar nicht hier in meinem Fall, wo es um einen Datenexport geht, bei dem
im Anschluss die csv zum Download angeboten wird.


> Rückwärts zu iterieren, wenn es auf die Reihenfolge nicht ankommt, ist in
> der Regel effizienter, weil der alte Wert der Iterationsvariablen nicht
> gespeichert werden muss:

Absolut d'accord!


> Wenn Du for..in-Schleifen verwendest, dann wird über alle aufzählbaren
> Eigenschaften des Objekts und seiner Prototypen iteriert. Das solltest Du
> vermeiden, denn Du weisst nie, welche Eigenschaften ein Objekt hat.
>
In diesem Fall schon. Die Daten kommen immer von der gleichen Funktion,
die diese aus einer Tabelle extrahiert. Das geht sogar soweit, dass ich
mir die String-Prüfeng auch noch sparen könnte. Habe das mal bei einer
größeren Datenmenge getestet uns es bringt gefühlt gar nichts, also habe
ich dieses Mindestmaß an Validierung drin gelassen.


> Über Array-Objekte wird modern so iteriert:
>
> data.forEach(callback);
>

Na ja, mit der Rückwärtsschleife haben wir die letzte ms raus geholt,
und nun verschenken wir sie vermutlich wieder. Vielleicht liege ich auch
falsch, aber ich kann mir nicht vorstellen, dass die Interpreter heute
in der Lage sind so was besser zu optimieren, wie eine handgemachte
Schleife - modern hin oder her.

Ehrlich, dieses Neumodische kotzt mich manchmal auch an. Hier werden
-zig neue Wege geschaffen, die letzten Endes zum gleichen Ergebnis
führen. Es gibt so ein altes Volkslied, bei dem sich immer die eine
Zeile wiederholt: "Aber schön muss sie sein..."


> Zusammenfassend:
>
> data.forEach(element => {
> Object.keys(element).forEach(function (key) {
> let value = this[key];
>
> if (typeof value === 'string')
> {
> this[key] = value.replace(/;/g, ',');
> }
> }, element);
> });
>

Und ist das jetzt schöner lesbar, als zwei ehrliche altmodische
Schleifen? Ist es schneller? Oder kompatibler? Moderner ja, aber sonst?

[...]
>
> "Draht;sw;0,5mm²;40°C...150°C"
>
> sind die Daten eindeutig. Bei
> "Draht,sw,0,5mm²,40°C...150°C"
> (das Ergebnis Deiner Ersetzung) ist das nicht mehr der Fall (ist das Komma
> dort ein Feldtrenner oder ist es ein Dezimalkomma?).

Damit, dass in der deutschen Sprache das Dezimaltrennzeichen das gleiche
ist wie das Nebensatztrennzeichen, damit muss unser Kulturraum leben,
was soll's... ;-)

Vielen Dank für deine (top) Anmerkungen und Ergänzungen.

Gruß
W. Wolf

Stefan Mayer

unread,
Sep 28, 2019, 8:25:09 AM9/28/19
to
Am Samstag, den 28.09.2019, 10:22 +0200 schrieb Wolfgang Wolf:

> [CSV Export]
> > "Draht;sw;0,5mm²;40°C...150°C"
> >
> > sind die Daten eindeutig. Bei
> > "Draht,sw,0,5mm²,40°C...150°C"
> > (das Ergebnis Deiner Ersetzung) ist das nicht mehr der Fall (ist das Komma
> > dort ein Feldtrenner oder ist es ein Dezimalkomma?).
>
> Damit, dass in der deutschen Sprache das Dezimaltrennzeichen das gleiche
> ist wie das Nebensatztrennzeichen, damit muss unser Kulturraum leben,
> was soll's... ;-)

Nach Millionen von erstellten und gelesenen Zeile hat sich für bei mir der Tab
als Feldtrenner und kein Wertebegrenzer sowie UTF-8 Zeichensatz als
praktikabelste Einstellung etabliert.

Wermutstropfen sind leider die vielen Nachfragen der Excelbenutzer :-)


> Vielen Dank für deine (top) Anmerkungen und Ergänzungen.

Da schließe mich an.


Schönen Tag noch.
ciao, Stefan

Thomas 'PointedEars' Lahn

unread,
Sep 28, 2019, 11:41:08 AM9/28/19
to
Wolfgang Wolf wrote:

> Am 26.09.2019 um 18:00 schrieb Thomas 'PointedEars' Lahn:
>> Wenn Du for..in-Schleifen verwendest, dann wird über alle aufzählbaren
>> Eigenschaften des Objekts und seiner Prototypen iteriert. Das solltest
>> Du vermeiden, denn Du weisst nie, welche Eigenschaften ein Objekt hat.
>
> In diesem Fall schon. Die Daten kommen immer von der gleichen Funktion,
> die diese aus einer Tabelle extrahiert.

Ausser Du kannst die Implementierungen eingrenzen, mit denen Dein Code
ausgeführt wird, weisst Du nie, welche aufzählbaren Eigenschaften ein Objekt
hat.

Siehe auch:

<http://PointedEars.de/es-matrix>

<https://github.com/airbnb/javascript>

In diesem Zusammenhang empfehle ich (aufgrund eigener, positiver Erfahrung)
die Verwendung von

<https://eslint.org/>

(Die Airbnb-Empfehlungen kann man sich zurechtbiegen, wenn es gar nicht
passen sollte. Man sollte das aber nur machen, wenn man weiss, was man
tut.)

> Das geht sogar soweit, dass ich mir die String-Prüfeng auch noch sparen
> könnte. Habe das mal bei einer größeren Datenmenge getestet uns es bringt
> gefühlt gar nichts, also habe ich dieses Mindestmaß an Validierung drin
> gelassen.

Wie gesagt erbt jedes eingebaute Objekt die .toString()-Methode von
Object.prototype(), so dass man damit (explizit oder implizit) jeden Wert
nach String konvertieren kann, um dann auf dem Ergebnis
String.prototype.replace() ausführen zu können. Das heisst aber nicht, dass
das Ergebnis auch sinnvoll ist oder dass das effizient ist. Die Prüfung auf
String ist also sinnvoll.

>> Über Array-Objekte wird modern so iteriert:
>>
>> data.forEach(callback);
>
> Na ja, mit der Rückwärtsschleife haben wir die letzte ms raus geholt,
> und nun verschenken wir sie vermutlich wieder.

Nein.

> Vielleicht liege ich auch falsch,

Das tust Du insofern, als dass die Funktion nur einmal compiliert werden
muss. Inwiefern die mehrfachen Aufrufe dann mehr Laufzeit kosten, müsste
man mal ausprobieren (normalerweise sind mehrfache Funktionsaufrufe
ineffizienter, bei Callbacks kann das aber anders sein).

> aber ich kann mir nicht vorstellen, dass die Interpreter heute
> in der Lage sind so was besser zu optimieren, wie eine handgemachte
> Schleife - modern hin oder her.

Ich schon.

> Ehrlich, dieses Neumodische kotzt mich manchmal auch an. Hier werden
> -zig neue Wege geschaffen, die letzten Endes zum gleichen Ergebnis
> führen. Es gibt so ein altes Volkslied, bei dem sich immer die eine
> Zeile wiederholt: "Aber schön muss sie sein..."

Das „Neumodische“ (jetzt auch schon wieder 10 Jahre alt; ECMAScript Ed. 5
wurde 2009 veröffentlicht und 2010 mit Mozilla JavaScript 1.8.2 erstmals
implementiert) ist auf jeden Fall weniger fehlerträchtig. Sämtliche
schleifenbezogenen Variablen sind auch dann automatisch im Scope begrenzt,
wenn man nicht Block-Scoping verwendet (das gab es bei der Einführung dieser
Methoden noch nicht), nämlich dadurch dass sie lokal im Callback sind.

>> Zusammenfassend:
>>
>> data.forEach(element => {
>> Object.keys(element).forEach(function (key) {
>> let value = this[key];
>>
>> if (typeof value === 'string')
>> {
>> this[key] = value.replace(/;/g, ',');
>> }
>> }, element);
>> });
>>
>
> Und ist das jetzt schöner lesbar, als zwei ehrliche altmodische
> Schleifen?

Ja. Da steht fast wörtlich genau, was gemacht werden soll, und man muss es
nicht erst aus der Schleifenlogik erraten.

> Ist es schneller?

Ob es *insgesamt* schneller ist, weiss ich nicht. Aber die nativ in C/C++
oder Java implementierten Schleifen der Script-Engines sind *sicher*
schneller als JIT-compilierte in ECMAScript.

> Oder kompatibler?

Nein, es gibt noch uralte Implementierungen mit < 1 % weltweitem
Marktanteil, die das nicht nativ unterstützen:

<http://pointedears.de/scripts/test/es-matrix/?filter=Array%5C.prototype%5C.forEach%7CObject%5C.keys>

Aber selbst dafür gibt es ja Babel.js & Co. oder man verwendet einen
Polyfill.

> [...]
>>
>> "Draht;sw;0,5mm²;40°C...150°C"
>>
>> sind die Daten eindeutig. Bei
>> "Draht,sw,0,5mm²,40°C...150°C"
>> (das Ergebnis Deiner Ersetzung) ist das nicht mehr der Fall (ist das
>> Komma dort ein Feldtrenner oder ist es ein Dezimalkomma?).
>
> Damit, dass in der deutschen Sprache das Dezimaltrennzeichen das gleiche
> ist wie das Nebensatztrennzeichen, damit muss unser Kulturraum leben,
> was soll's... ;-)

Das ist keine Frage der Sprache, sondern landesspezifisch. In der
deutschsprachigen Schweiz zum Beispiel, wo ich seit geraumer Zeit lebe, wird
in der Regel mindestens bei Geldbeträgen der Punkt als Dezimaltrennzeichen
verwendet:

<https://www.bk.admin.ch/bk/de/home/dokumentation/sprachen/hilfsmittel-textredaktion/schreibweisungen.html>

Dort Abschnitt 5.1.3.

(Das war meine Referenz, als ich an <https://www.priminfo.admin.ch/>
mitarbeitete.)

Siehe auch: <https://de.wikipedia.org/wiki/Schreibweise_von_Zahlen>

Das Komma ist übrigens im Deutschen nicht ausschliesslich ein
„Nebensatztrennzeichen“:

<https://www.duden.de/sprachwissen/rechtschreibregeln>

Siehe dort u.a. D11, D32, und D100 bis D132.

> Vielen Dank für deine (top) Anmerkungen und Ergänzungen.

Bitte, danke.

Wolfgang Wolf

unread,
Oct 7, 2019, 9:59:12 AM10/7/19
to
Am 28.09.2019 um 14:25 schrieb Stefan Mayer:

>
> Wermutstropfen sind leider die vielen Nachfragen der Excelbenutzer :-)
>
>

Das ist leider kein Wermutstropfen, sondern eine ganze Badewanne voll
Tränen. Wie läuft es denn in der Praxis ab? Der Anwender klickt auf
"Export" oder ähnlich und der Browser bietet einen Dialog mit "Datei
speichern" oder "Öffnen mit...". Hinter "Öffnen mit..." verbirgt sich
i.d.R. (also bei meinen Anwendern ganz sicher) ein Excel, welches ohne
irgendwelche Sonder-Konfigurationen eine Semikolon-getrennte CSV
anstandslos ließt und darstellt. Wenn die Kodierung und das BOM auch
noch stimmen, werden sogar die Sonderzeichen korrekt dargestellt. Für
alles andere muss der Text-Import-Assistent herhalten, der zwar mit
allen unterschiedlichen Konfigurationen klar kommt, aber halt nicht so
komfortabel ist, wie konfigurationsloses Direktladen.

Schönen Gruß
W. Wolf

Wolfgang Wolf

unread,
Oct 7, 2019, 10:06:27 AM10/7/19
to
Am 28.09.2019 um 17:41 schrieb Thomas 'PointedEars' Lahn:
> Ausser Du kannst die Implementierungen eingrenzen, mit denen Dein Code
> ausgeführt wird...

Genau das meinte ich mit "immer von der gleichen Funktion". Diese
Funktion wird mit einem Template gefüttert. Dort enthalten sind bereits
die Semikolons als Feldtrennzeichen (hier könnte ich natürlich auch ein
anderes Zeichen verwenden, macht aber zusammen mit Excel nur bedingt
Sinn (s. Antwort an Stefan).

Läuft alles inzwischen ganz gut - bin happy! Danke!

Schönen Gruß
W. Wolf

Stefan Mayer

unread,
Oct 7, 2019, 6:42:55 PM10/7/19
to
Sehr trefflich. Erstaunlich, dass das nicht besser funktioniert.

LibreOffice wenigstens bietet beim Öffnen eine passenden Dialog an und merkt
sich die Einstellung. Immerhin, wenn es die Zielgruppe kennen würde.

ciao, Stefan


Thomas 'PointedEars' Lahn

unread,
Oct 9, 2019, 7:26:17 PM10/9/19
to
Wolfgang Wolf wrote:

> Am 28.09.2019 um 17:41 schrieb Thomas 'PointedEars' Lahn:
>> Ausser Du kannst die Implementierungen eingrenzen, mit denen Dein Code
>> ausgeführt wird...
>
> Genau das meinte ich mit "immer von der gleichen Funktion". Diese
> Funktion wird mit einem Template gefüttert. Dort enthalten sind bereits
> die Semikolons als Feldtrennzeichen (hier könnte ich natürlich auch ein
> anderes Zeichen verwenden, macht aber zusammen mit Excel nur bedingt
> Sinn (s. Antwort an Stefan).

Anscheinend hast Du nicht verstanden, was mit „Implementierung“ gemeint ist.
Gemeint ist die Implementierung *von ECMAScript*; je nach Laufzeitumgebung,
z. B. Web-Browser, ist das eine *andere*. Siehe ECMAScript Support Matrix.

Wolfgang Wolf

unread,
Nov 12, 2019, 10:58:50 AM11/12/19
to
Am 10.10.2019 um 01:26 schrieb Thomas 'PointedEars' Lahn:

>
> Anscheinend hast Du nicht verstanden, was mit „Implementierung“ gemeint ist.
> Gemeint ist die Implementierung *von ECMAScript*; je nach Laufzeitumgebung,
> z. B. Web-Browser, ist das eine *andere*. Siehe ECMAScript Support Matrix.
>

Ne, habe ich nicht. Warum soll denn der Web-Browser aus dem von mir im
Code festgelegtem Semikolon ein anderes Zeichen machen? Sorry, verstehe
ich nicht - macht aber nichts.

Schönen Gruß
W. Wolf

Thomas 'PointedEars' Lahn

unread,
Nov 12, 2019, 7:04:58 PM11/12/19
to
Wolfgang Wolf wrote:

> Am 10.10.2019 um 01:26 schrieb Thomas 'PointedEars' Lahn:
>> Anscheinend hast Du nicht verstanden, was mit „Implementierung“ gemeint
>> ist. Gemeint ist die Implementierung *von ECMAScript*; je nach
>> Laufzeitumgebung, z. B. Web-Browser, ist das eine *andere*. Siehe
>> ECMAScript Support Matrix.
>
> Ne, habe ich nicht. Warum soll denn der Web-Browser aus dem von mir im
> Code festgelegtem Semikolon ein anderes Zeichen machen?

Lern lesen. Ich schrieb über die AUFZÄHLBAREN EIGENSCHAFTEN EINES OBJEKTS.

> Sorry, verstehe ich nicht - macht aber nichts.

Das Statement eines Ignoranten. Wenn Du nichts wissen willst, weshalb
fragst Du überhaupt?

Wolfgang Wolf

unread,
Nov 14, 2019, 5:48:45 AM11/14/19
to
Am 13.11.2019 um 01:04 schrieb Thomas 'PointedEars' Lahn:

> Lern lesen. Ich schrieb über die AUFZÄHLBAREN EIGENSCHAFTEN EINES OBJEKTS.
>

Habe ich ab der ersten Klasse gelernt, davor hat man mir gutes Benehmen
beigebracht.

Ich bin nur deshalb auf die "AUFZÄHLBAREN EIGENSCHAFTEN EINES OBJEKTS"
nicht gekommen, weil ich mich auf deinen Satz:

> ...denn Du weisst nie, welche Eigenschaften ein Objekt hat.

mit "In diesem Fall schon. Die Daten kommen immer von der gleichen
Funktion." geantwortet habe. Somit war für mich dieses Thema abgehackt.

>> Sorry, verstehe ich nicht - macht aber nichts.
>
> Das Statement eines Ignoranten. Wenn Du nichts wissen willst, weshalb
> fragst Du überhaupt?
>

Ich wollte nicht "nichts" wissen, sondern was anderes. Hast mir ja auch
hervorragend geantwortet, wofür ich dir gedankt habe. Wenn du allerdings
meinst, dass deine Antwort noch diese Ergänzungen brauchen, bitte schön
- bin dir nicht wirklich böse... ;-)

Schönen Gruß
W. Wolf

Thomas 'PointedEars' Lahn

unread,
Nov 14, 2019, 1:27:29 PM11/14/19
to
Wolfgang Wolf wrote:

> Am 13.11.2019 um 01:04 schrieb Thomas 'PointedEars' Lahn:
>> Lern lesen. Ich schrieb über die AUFZÄHLBAREN EIGENSCHAFTEN EINES
>> OBJEKTS.
>
> Habe ich ab der ersten Klasse gelernt, davor hat man mir gutes Benehmen
> beigebracht.

Hat offenbar beides nicht lange angehalten.

> Ich bin nur deshalb auf die "AUFZÄHLBAREN EIGENSCHAFTEN EINES OBJEKTS"
> nicht gekommen, weil ich mich auf deinen Satz:
>
> > ...denn Du weisst nie, welche Eigenschaften ein Objekt hat.
>
> mit "In diesem Fall schon. Die Daten kommen immer von der gleichen
> Funktion." geantwortet habe. Somit war für mich dieses Thema abgehackt.

Es spielt keine Rolle, ob es sich um die gleiche Funktion handelt.
Es handelt sich nicht immer um die gleiche Laufzeitumgebung.

>>> Sorry, verstehe ich nicht - macht aber nichts.
>>
>> Das Statement eines Ignoranten. Wenn Du nichts wissen willst, weshalb
>> fragst Du überhaupt?
>
> Ich wollte nicht "nichts" wissen, sondern was anderes.

Eben, das ist ignorant; denn das, was Du nun erfahren hast, hat mit dem, was
Du ursprünglich wissen wolltest, unmittelbar zu tun.

Erst liest Du nicht richtig hin und dann behauptest Du, das von Dir nicht
richtig Gelesene habe keine Bedeutung. Das ist nicht nur ignorant, sondern
auch frech.

Wolfgang Wolf

unread,
Nov 15, 2019, 6:51:11 AM11/15/19
to
Am 14.11.2019 um 19:27 schrieb Thomas 'PointedEars' Lahn:

> Es spielt keine Rolle, ob es sich um die gleiche Funktion handelt.
> Es handelt sich nicht immer um die gleiche Laufzeitumgebung.
>

Falsch! Die Laufzeitumgebung spielt hier keine Rolle, weil ich durch
alle Eigenschaften eines Objektes iteriere. Das schließt die
Eigenschaften, dich ich selbst implementiert habe ein. Ob darüber hinaus
eine Laufzeitumgebung weitere Eigenschaften aufzählt, die eine andere
nicht kennt ist egal, weil mich diese (im konkreten Fall) nicht
interessieren. Und sollte irgendeine Laufzeit gar nicht iterieren wollen
- Gott, oh Gott! Dann werden die Semikolons halt nicht ersetzt.

Um dennoch die Kirche im Dorf zu lassen: Hast natürlich vollkommen
recht, wenn man die Sache global und jenseits von meinem Kontext sieht.
Sorry für meine Provokationen, hoffe du kannst jetzt wieder ruhiger
schlafen.

> Das ist nicht nur ignorant, sondern auch frech.

Du schmeichelst mir!

Schönen Gruß
W. Wolf

Thomas 'PointedEars' Lahn

unread,
Nov 15, 2019, 10:22:56 PM11/15/19
to
Wolfgang Wolf wrote:

> Am 14.11.2019 um 19:27 schrieb Thomas 'PointedEars' Lahn:
>> Es spielt keine Rolle, ob es sich um die gleiche Funktion handelt.
>> Es handelt sich nicht immer um die gleiche Laufzeitumgebung.
>
> Falsch! Die Laufzeitumgebung spielt hier keine Rolle, weil ich durch
> alle Eigenschaften eines Objektes iteriere.

Falsch.

> Das schließt die Eigenschaften, dich ich selbst implementiert habe ein. Ob
> darüber hinaus eine Laufzeitumgebung weitere Eigenschaften aufzählt, die
> eine andere nicht kennt ist egal, weil mich diese (im konkreten Fall)
> nicht interessieren.

Dann bist Du einfach DUMM. Denn aufzählbare Eigenschaften, die Du nicht
definiert hast, verfälschen das Ergebnis. Somit liefert Dein Code in
unterschiedlichen Laufzeitumgebungen und mit unterschiedlichen zusätzlich
geladenen Bibliotheken unterschiedliche Ergebnisse. Das Ergebnis der
Ausführung Deines Codes ist also nicht vorhersagbar.

> Und sollte irgendeine Laufzeit gar nicht iterieren wollen

Du hast also keine blasse Ahnung, was „Laufzeitumgebung“ bedeutet.

> - Gott, oh Gott! Dann werden die Semikolons halt nicht ersetzt.

Was TATSÄCHLICH passiert ist, dass der Code AUSGEFÜHRT wird und somit
data[i] anschliessend Eigenschaften haben kann, von denen Du gar nicht
wolltest, dass es sie hat. Denn

var dProp = data[i][prop];
if (typeof dProp == "string") {
data[i][prop] = dProp.replace(/;/g,",");
}

fügt data[i] die Eigenschaft, deren Name durch den Wert von “prop” definiert
wird, hinzu, falls es diese Eigenschaft noch nicht hatte, aber irgendein
Objekt in der Prototyp-Kette von data[i] diese aufzählbare Eigenschaft hat,
da

for (var prop in data[i]) {
/* … */
}

genau über alle DIESE Eigenschaften iteriert. Daher:

<https://eslint.org/docs/rules/guard-for-in>

> Um dennoch die Kirche im Dorf zu lassen: Hast natürlich vollkommen
> recht, wenn man die Sache global und jenseits von meinem Kontext sieht.
> Sorry für meine Provokationen, hoffe du kannst jetzt wieder ruhiger
> schlafen.
>
> > Das ist nicht nur ignorant, sondern auch frech.
>
> Du schmeichelst mir!

Offenbar bist Du einfach zu dumm (für eine sinnvolle Diskussion).

Score adjusted.

Stefan Mayer

unread,
Nov 16, 2019, 7:42:35 AM11/16/19
to
Am 16.11.2019, 04:22 schrieb Thomas 'PointedEars' Lahn:

> for (var prop in data[i]) {
> /* … */
> }
>
>
> <https://eslint.org/docs/rules/guard-for-in>
>

Könntest Du mal ein Beispiel zeigen/verlinken in dem das unerwartet
Verhalten sichtbar wird?


--
ciao, Stefan

Wolfgang Wolf

unread,
Nov 16, 2019, 7:45:43 AM11/16/19
to
Am 16.11.2019 um 04:22 schrieb Thomas 'PointedEars' Lahn:

>
> Dann bist Du einfach DUMM. Denn aufzählbare Eigenschaften, die Du nicht
> definiert hast, verfälschen das Ergebnis. Somit liefert Dein Code in
> unterschiedlichen Laufzeitumgebungen und mit unterschiedlichen zusätzlich
> geladenen Bibliotheken unterschiedliche Ergebnisse. Das Ergebnis der
> Ausführung Deines Codes ist also nicht vorhersagbar.

Das ist arrogant und idiotisch. Dass es darüber hinaus auch noch
beleidigend ist zeugt davon, dass Fachgespräche mit dir nicht möglich sind.

Meine Daten
data = [
{
artnr: "ACW0219-0.50-0",
benennung: "Draht;sw;0,5mm²;40°C...150°C",
​​ bestand: "85,20"
},...
]
deren Aufbau und Zusammensetzung ich alleine bestimme, werden so wie sie
sind an irgend eine andere Funktion übergeben. Da gibt es keine
vererbten Propertys und auch sonnst nichts Verstecktes. Das sind Arrays
von plumpen Wertetypen, genau genommen sind es immer Strings, weil
selbst die enthaltenen Zahlen als Zeichenketten definiert sind.

Dazwischen ersetze ich nun in meiner Schleife alle Semikolons durch ein
anderes Zeichen. Die Laufzeitumgebung, die an dieser Stelle etwas
zusätzlich hinein baut, gibt es nur in deiner Phantasie und die, kannst
ruhig in die Tonne treten (Phantasie oder Laufzeit ist egal). Meine
Anwendung wird halt mit so einer Phantasie-Laufzeit ganz einfach nicht
klar kommen und das geht mir so was von am Ärmel vorbei, wie inzwischen
deine Beleidigungen.

Schönen Gruß
W. Wolf


Thomas 'PointedEars' Lahn

unread,
Nov 16, 2019, 8:51:30 AM11/16/19
to
Ja. Gibt’s aber auch ohne Ende im Web.

Thomas 'PointedEars' Lahn

unread,
Nov 16, 2019, 8:55:18 AM11/16/19
to
Wolfgang Wolf wrote:

> Am 16.11.2019 um 04:22 schrieb Thomas 'PointedEars' Lahn:
>> Dann bist Du einfach DUMM. Denn aufzählbare Eigenschaften, die Du nicht
>> definiert hast, verfälschen das Ergebnis. Somit liefert Dein Code in
>> unterschiedlichen Laufzeitumgebungen und mit unterschiedlichen zusätzlich
>> geladenen Bibliotheken unterschiedliche Ergebnisse. Das Ergebnis der
>> Ausführung Deines Codes ist also nicht vorhersagbar.
>
> Das ist arrogant und idiotisch.

Nein, dass das passiert, ist eine TATSACHE.

> Dass es darüber hinaus auch noch beleidigend ist.

Ist es nicht, denn ist eine TATSACHE, dass sich Script-Engines so verhalten:
unter anderem ist es so STANDARDISIERT:

<https://www.ecma-international.org/ecma-262/#sec-for-in-and-for-of-statements>

Und dies zu IGNORIEREN, IST schlicht dumm.

Thomas 'PointedEars' Lahn

unread,
Nov 16, 2019, 8:57:41 AM11/16/19
to
Wolfgang Wolf wrote:

> Am 16.11.2019 um 04:22 schrieb Thomas 'PointedEars' Lahn:
>> Dann bist Du einfach DUMM. Denn aufzählbare Eigenschaften, die Du nicht
>> definiert hast, verfälschen das Ergebnis. Somit liefert Dein Code in
>> unterschiedlichen Laufzeitumgebungen und mit unterschiedlichen zusätzlich
>> geladenen Bibliotheken unterschiedliche Ergebnisse. Das Ergebnis der
>> Ausführung Deines Codes ist also nicht vorhersagbar.
>
> Das ist arrogant und idiotisch.

Nein, dass das passiert, ist eine TATSACHE.

> Dass es darüber hinaus auch noch beleidigend ist.

Ist es nicht, denn ist eine TATSACHE, dass sich Script-Engines so verhalten:
unter anderem ist es so STANDARDISIERT:

<https://www.ecma-international.org/ecma-262/#sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation>

Und dies zu IGNORIEREN, IST schlicht dumm.

Wolfgang Wolf

unread,
Nov 18, 2019, 4:08:02 AM11/18/19
to
Am 16.11.2019 um 14:57 schrieb Thomas 'PointedEars' Lahn:

> Nein, dass das passiert, ist eine TATSACHE.
>
>> Dass es darüber hinaus auch noch beleidigend ist.
>
> Ist es nicht, denn ist eine TATSACHE, dass sich Script-Engines so verhalten:
> unter anderem ist es so STANDARDISIERT:
>
> <https://www.ecma-international.org/ecma-262/#sec-for-in-and-for-of-statements-runtime-semantics-labelledevaluation>
>

Falls es dir nur darum geht, hier immer das letzte Wort zu haben, dann
sag das bitte. Wir können uns das einfacher machen und ich werde auf
deine Post nicht mehr antworten.

> Und dies zu IGNORIEREN, IST schlicht dumm.
>

Nur mit Paragrafen zu argumentieren und die Tatsachen auszublenden ist
genauso ignorant. Stefan hat dich um ein Beispiel gebeten, dass du
anscheinend nicht liefern kannst. Wenn du wirklich auf deinen Thesen
beharrst, bitte ich dich auch darum eine Laufzeit zu benennen, die in
meinen trivial simplen Code irgendwelche zusätzliche Eigenschaften dort
findet oder wie auch immer selbst einfügt. Und selbst wenn es das geben
sollte, wird mein Replace dort (sofern es sich um Strings handelt), ein
Semikolon (sofern dort eins vorhanden ist) durch ein Komma ersetzten und
damit ein Problem bekommen oder auch nicht. Wenn alle "wenns"
zutreffen, bekomme ich vielleicht wieder ein Verstümmeltes CSV, also das
was ich vorher schon hatte. Na und?

Und zu deinen "sonstigen" Anmerkungen: Ist dir schon aufgefallen, dass
du hier auffällst? Ist es das, was du willst? Vermutlich bist ein
schlauer, fachlich hervorragender aber sonst armer, introvertierter und
einsamer Geselle, der sich nur im Schutze der Web-Anonymität was traut
und dabei voll übers Ziel hinaus schießt. Du tust mir leid.

Schönen Gruß
W. Wolf

Stefan Mayer

unread,
Nov 18, 2019, 5:56:09 AM11/18/19
to
Am Samstag, den 16.11.2019, 14:51 +0100 schrieb Thomas 'PointedEars'
Lahn:
> Stefan Mayer wrote:
>
> > Am 16.11.2019, 04:22 schrieb Thomas 'PointedEars' Lahn:
> > > for (var prop in data[i]) {
> > > /* … */
> > > }
> > >
> > >
> > > <https://eslint.org/docs/rules/guard-for-in>
> >
> > Könntest Du mal ein Beispiel zeigen/verlinken in dem das unerwartet
> > Verhalten sichtbar wird?
>
> Ja. Gibt’s aber auch ohne Ende im Web.

OK. Selbst rausgefunden :-)

```
Array.prototype.Wert4 = "Außerhalb von 'werte' definiert.";

const werte = [
'Wert1',
'Wert2',
'Wert3'
];
console.log(werte);
// [ 'Wert1', 'Wert2', 'Wert3' ]

for (let i in werte) {
console.log(`${i}: ${werte[i]}`)
}
// 0: Wert1
// 1: Wert2
// 2: Wert3
// Wert4: Außerhalb von 'werte' definiert. < Bingo: Unerwartet.
```

Deshalb die Prüfung "hasOwnProperty" in "for in" Schleifen. Oder eben
gleich "forEach"


```
werte.forEach((wert, i) => {
console.log(`${i}: ${wert}`)
})

// 0: Wert1
// 1: Wert2
// 2: Wert3
```

Puh, da bin ich ja froh, dass ich "forEach" schon immer hübscher fand.


Wenn man allerdings mit dem Index hantiert, ist "Wert4" nicht da, weil
nicht explizit in "werte" vorhanden. Richtig?

```
for (let i = 0; i < werte.length; i++) {
console.log(`${i}: ${werte[i]}`);
}
// 0: Wert1
// 1: Wert2
// 2: Wert3
```

--
ciao, Stefan


Wolfgang Wolf

unread,
Nov 18, 2019, 7:50:57 AM11/18/19
to
Am 18.11.2019 um 11:56 schrieb Stefan Mayer:

> Puh, da bin ich ja froh, dass ich "forEach" schon immer hübscher fand.
>

const werte = ['Wert1','Wert2','Wert3'];
for (let i in werte) console.log(werte[i]);
werte.forEach(wert => console.log(wert));

Das funktioniert im Firefox und bringt einen Fehler im IE (W7-64, alle
getesteten Emulationen). Übrigens den gleichen (Syntax-) Fehler wie auch
Thomas Empfehlung für meinen Code.

Beschrieben ist das hier:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/For-each-in_loops_are_deprecated

Was nützen mir also alle theoretischen Erkenntnisse und hübsche
Lösungen, wenn sie in der Praxis nicht funktionieren?

Schönen Gruß
W. Wolf



Stefan Mayer

unread,
Nov 18, 2019, 9:43:34 AM11/18/19
to
Am Montag, den 18.11.2019, 13:50 +0100 schrieb Wolfgang Wolf:
> Am 18.11.2019 um 11:56 schrieb Stefan Mayer:
>
> > Puh, da bin ich ja froh, dass ich "forEach" schon immer hübscher
> > fand.
> >
>
> const werte = ['Wert1','Wert2','Wert3'];
> for (let i in werte) console.log(werte[i]);
> werte.forEach(wert => console.log(wert));
>
> Das funktioniert im Firefox und bringt einen Fehler im IE (W7-64,
> alle getesteten Emulationen). Übrigens den gleichen (Syntax-) Fehler
> wie auch Thomas Empfehlung für meinen Code.


Stichwort: ES6

Pfeilfunktionen sind in IE nicht verfügbar.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Alternativ wäre:
```
werte.forEach(function(wert){console.log(wert)})
```
Da geht es um das Konstrukt "for each (for in)".


Was nicht das Gleiche wie "Array.forEach" ist? Ich bin offenkundig
kein ECMA-Experte, noch nicht einmal Novize, deshalb das Fragezeichen.

Interessant ist, dass als "Alternative standard syntax" die
problematische "for in" Schleife, ohne Hinweis auf die Gefahr, genannt
wird.


> Was nützen mir also alle theoretischen Erkenntnisse und hübsche
> Lösungen, wenn sie in der Praxis nicht funktionieren?

Wenig?


Allerdings gibt es mit "for in" das aufgezeigt Problem. Da halte ich es
wie Kirk. Die "Schätzung" von Thomas ist mir lieber als das stundenlange
rechnen des Bordcomputers. Das er ansonsten wenig soziale Kompetenz
aufweist … nun ja, das muss man einfach überlesen.

Wolfgang Wolf

unread,
Nov 18, 2019, 10:40:22 AM11/18/19
to
Am 18.11.2019 um 15:43 schrieb Stefan Mayer:

>
> Da geht es um das Konstrukt "for each (for in)".
>
>
> Was nicht das Gleiche wie "Array.forEach" ist? Ich bin offenkundig
> kein ECMA-Experte, noch nicht einmal Novize, deshalb das Fragezeichen.
>

Ups, habe ich übersehen. Wie dem auch sei: andere Ursache, dennoch
Fehler im IE.

> Interessant ist, dass als "Alternative standard syntax" die
> problematische "for in" Schleife, ohne Hinweis auf die Gefahr, genannt
> wird.

Konnte allerdings dein Beispiel nicht mit meinen Daten reproduzieren.
Und alle Browser, die ich hier im Haus getestet habe (die drei Großen)
liefern jetzt korrekte Daten. Damit kann ich gut leben. Davor haben alle
drei das CSV verstümmelt, was aber nicht an der Browsern oder an
JavaScript lag - letzten Endes ist es ja eine "Unzulänglichkeit" von
Excel. Ich muss das pragmatisch sehen: "Entscheidend ist, was hinten
raus kommt" (Politiker-Zitat)

Gruß
W. Wolf

Stefan Mayer

unread,
Nov 18, 2019, 3:32:54 PM11/18/19
to
Am Montag, den 18.11.2019, 16:40 +0100 schrieb Wolfgang Wolf:

> Konnte allerdings dein Beispiel nicht mit meinen Daten reproduzieren.

Ich auch nicht. Wahrscheinlich nur günstige Umstände.


> "Entscheidend ist, was hinten raus kommt"

Natürlich, nur bei einer ungesicherten "for in"-Schleife muss das nicht
immer das Beste sein. :-)

Schönen Abend noch.
ciao, Stefan

PS: Du verarbeitest CSV-Daten per JavaScript im Browser. Wieviele Zeilen
sind das so und wie kommen die das Script?

Thomas 'PointedEars' Lahn

unread,
Nov 18, 2019, 6:03:30 PM11/18/19
to
Stefan Mayer wrote:

> Array.prototype.Wert4 = "Außerhalb von 'werte' definiert.";
>
> const werte = [
> 'Wert1',
> 'Wert2',
> 'Wert3'
> ];
> console.log(werte);
> // [ 'Wert1', 'Wert2', 'Wert3' ]
>
> for (let i in werte) {
> console.log(`${i}: ${werte[i]}`)
> }
> // 0: Wert1
> // 1: Wert2
> // 2: Wert3
> // Wert4: Außerhalb von 'werte' definiert. < Bingo: Unerwartet.
> ```
>
> Deshalb die Prüfung "hasOwnProperty" in "for in" Schleifen. Oder eben
> gleich "forEach"

Genau.

>
> ```
> werte.forEach((wert, i) => {
> console.log(`${i}: ${wert}`)
> })
>
> // 0: Wert1
> // 1: Wert2
> // 2: Wert3
> ```
>
> Puh, da bin ich ja froh, dass ich "forEach" schon immer hübscher fand.

Das gab es aber nicht immer (wurde mit ECMAScript Edition 5 vor ca. 9 Jahren
eingeführt). Aber letztlich ist Array.prototype.forEach() auch nichts
anderes als eine for-Schleife mit Callback. Kann man leicht selbst
implementieren (hab’ ich auch für meine ECMAScript-Referenzimplementierung),
z. B. (wahrscheinlich unvollständig, siehe Spezifikation):

Array.prototype.forEach = function (callback, thisValue) {
if (!thisValue) thisValue = this;

var _hasOwnProperty = ({}).hasOwnProperty;

for (var i = 0, len = this.length; i < len; ++i)
{
if (_hasOwnProperty.call(this, i))
{
callback.call(thisValue, this[i], i, this);
}
}
};

foreach() bzw. diese for-Schleife hat aber den Nachteil, dass sie sehr
ineffizient bei “sparse arrays” ist, d. h. wo eine signifikante Anzahl
Array-Elemente nicht definiert sind:

let a = [];
a[Math.pow(2, 31)] = 42;

Das iteriert dann sehr lange, führt aber z. B. den Callback nur einmal aus.
Hingegen ist die Iteration mit

var _hasOwnProperty = ({}).hasOwnProperty;

/* bzw. “for (let name in a)“
for (var name in a)
{
if (parseInt(name, 10) == +name
|| !_hasOwnProperty.call(a, name))
{
continue;
}

/* … */
}

vergleichsweise schnell (ich habe auch absichtlich die Logik umgekehrt, um
durch schnelle Auswertung die Effizienz noch einmal zu steigern. Leider
gibt es keinen direkten Weg, herauszufinden, ob eine Array-artige
Datenstruktur “sparse” ist; jedoch kann .length einen Hinweis geben (ist es
sehr gross, dann ist die Wahrscheinlichkeit höher, dass die Struktur
“sparse” ist.

Ausserdem könnte man einmalig in einer kleinen Anzahl Schritte pseudo-
zufällig über die Struktur mit bis maximal .length - 1 iterieren und zählen,
wie oft man dabei (mit in-Operator und Object.prototype.hasOwnProperty(),
oder Array.prototype.contains() über die Keys) ins Leere griff. Wird dabei
ein kritischer Wert überschritten, kann man annehmen, dass die Struktur
“sparse” ist und mit for-in statt for(each)-Iteration arbeiten.

> Wenn man allerdings mit dem Index hantiert, ist "Wert4" nicht da, weil
> nicht explizit in "werte" vorhanden. Richtig?

Nein. Zwar ist die Eigenschaft mit Name „Wert4“ tatsächlich keine des
Array-artigen Objekts selbst; aber das spielt keine Rolle, weil Du bei der
Iteration gar nicht mehr auf diese Eigenschaft zuzugreifen versuchst.

> ```
> for (let i = 0; i < werte.length; i++) {

Effizienter:

for (let i = 0, werte.length; i < len; ++i)
{

Wenn es auf die Reihenfolge nicht ankommt,

for (let i = werte.length; i--)
{

wobei man mit dem i-- wieder einen Teil der Effizienz einbüsst.

Wolfgang Wolf

unread,
Nov 19, 2019, 1:49:17 AM11/19/19
to
Am 18.11.2019 um 21:32 schrieb Stefan Mayer:

> Natürlich, nur bei einer ungesicherten "for in"-Schleife muss das nicht
> immer das Beste sein. :-)
>
Bin ich bei dir (und auch bei Thomas). Wenn ich diese Objekte nicht
kenne, hätte ich nun nach dieser Diskussion auch gewisse Zweifel. Ich
kenne sie aber weil ich sie selbst erzeuge, bzw. erzeuge ich so was wie
ein Objekt-Template, welches von einer Sencha-Ext-Funktion mit den Daten
einer Tabelle befüllt wird. Daher sind in den Eigenschaften der Objekte
immer nur Strings (die Properties entsprechen den Tabellen-Spalten,
jedoch immer als String). Man könnte auch spezialisierte Templates
verwenden, die sich immer an den Datentypen der Spalten orientieren, für
den CSV-Export reichen mir hier die Strings. Damit kann ich den Export
universell halten.

Nach dem Befüllen der Templates habe ich also ein Array mit
gleichartigen Objekten, eines per Tabellen-Zeile. Dieses Array wird von
einer weiteren Funktion in ein CSV umgewandelt. Ich musste lediglich
davor dazwischen gehen und die Semikolons in den Texten ersetzen.

>
> PS: Du verarbeitest CSV-Daten per JavaScript im Browser. Wieviele Zeilen
> sind das so und wie kommen die das Script?
>

Das ist übertrieben. Ich verarbeite keine CSV-Daten, sondern erzeuge
sie. Die Anzahl der Zeilen ist von der Source-Tabelle abhängig. Da in
der Tabelle aber Paging verwendet wird, sind es i.d.R. überschaubare
Datenzeilen.

Schönen Gruß
W. Wolf

Thomas 'PointedEars' Lahn

unread,
Nov 19, 2019, 12:48:29 PM11/19/19
to
Thomas 'PointedEars' Lahn wrote:

> Stefan Mayer wrote:
>> for (let i = 0; i < werte.length; i++) {
>
> Effizienter:
>
> for (let i = 0, werte.length; i < len; ++i)
> {

Gemeint war:

for (let i = 0, len = werte.length; i < len; ++i)
{

Andernfalls wäre der initiale Wert von i der Wert von werte.length, da dann
das Komma als Komma-Operator interpretiert werden würde: der Wert der Komma-
Operation ist der letzte Operand.

Stefan Mayer

unread,
Nov 19, 2019, 1:42:15 PM11/19/19
to
Dienstag, den 19.11.2019, Thomas 'PointedEars' Lahn:
> Thomas 'PointedEars' Lahn wrote:
>
> > Stefan Mayer wrote:
> > > for (let i = 0; i < werte.length; i++) {
> >
> > Effizienter:
> >
> > for (let i = 0, werte.length; i < len; ++i)
> > {
>
> Gemeint war:
>
> for (let i = 0, len = werte.length; i < len; ++i)
> {
>
> Andernfalls wäre der initiale Wert von i der Wert von werte.length, da
> dann das Komma als Komma-Operator interpretiert werden würde: der Wert
> der Komma-Operation ist der letzte Operand.

Herzlichen Dank für Dein lehrreichen Ausführungen.

Stefan Mayer

unread,
Nov 20, 2019, 2:31:57 PM11/20/19
to
Am Dienstag, 19.11.2019, Thomas 'PointedEars' Lahn:

> > > for (var prop in data[i]) {
> > > /* … */
> > > }
> > >
> > > <https://eslint.org/docs/rules/guard-for-in>
> > >
> > Puh, da bin ich ja froh, dass ich "forEach" schon immer hübscher
> > fand.

> Das gab es aber nicht immer (wurde mit ECMAScript Edition 5 vor ca. 9
> Jahren eingeführt). Aber letztlich ist Array.prototype.forEach() auch
> nichts anderes als eine for-Schleife mit Callback.

So ein Polyfill war natürlich der obligatorische Begleiter zu der Zeit.
Auch für "NodeList".

Bemerkenswert ist, dass es sowohl das Problem als auch dessen Lösung
aufzeigt, bzw. an sich den Sachverhalt verkörpert. Die ganze Zeit über
vor meiner Nase …


> a[Math.pow(2, 31)] = 42;

In meinem Fall lautet die Antwort: forEach


ciao, Stefan


0 new messages