effel: Rückspeichern in Argument

Hallo,

ich habe eine Frage:

eine function erhält über ein Argument ein Array. Das Array wird anschließend bearbeitet. Anschließend wird das Ergebnis in eben dies Argument gespeichert. Bei mir hat das funktioniert. return(arg2) ist nicht nötig.

Danke für die Hilfe

Effel

aufruf: /*m16a=*/ trennen1(anz_1,m16a,0); //ergeb in m16.. gespeichert 

function trennen1(arg1,arg2,arg3){
var z0;
var z1;
var z2;
var anzx01=[];
var anzx02=[];
var anzx=[];
anzx=anzx.concat(arg1);
z0=0;
z1=0;
z2=0;
while (z0 < anzx.length){
if(anzx[z0]%2==0){
anzx01[z1]=korr005(anzx[z0]);
z1++;
 }else{
anzx02[z2]=korr005(anzx[z0]);
z2++;
 }
 z0++;
  }
arg3=0;  
if(anzx01.length>0){
arg2[arg3]=anzx01
arg3=arg3+1
   }
if(anzx02.length>0){
arg2[arg3]=anzx02
   }
//return(arg2); //ergeb in m16.. gespeichert
}
  1. Hi,

    ich habe eine Frage:

    Nö, hast Du nicht. Denn das hier

    eine function erhält über ein Argument ein Array. Das Array wird anschließend bearbeitet. Anschließend wird das Ergebnis in eben dies Argument gespeichert. Bei mir hat das funktioniert. return(arg2) ist nicht nötig.

    ist ohne Frage [sorry, could not resist] eine Feststellung, keine Frage.

    cu,
    Andreas a/k/a MudGuard

    1. Hallo Rolf,

      ich bedanke mich für die ausführliche Darstellung !!

      • viele neue Erkenntnisse !

      Meine Frage ist aber anders: Was wird im Argument einer Funktion übergeben? Vermute: bei Arrays wird die Adresse übergeben, bei einfachen Werten wird der WERT übergeben

      Dann ermöglicht die Adresse des Array eine Neubelegung des Arrays

      Ich benötige über dieses eine klare >Information.

      Ich bedanke mich dafür!

      Gruß Effel

      1. Hallo effel,

        JavaScript übergibt Argumente grundsätzlich als Wert. Referenzparameter gibt es nicht.

        Was verwirren kann, ist die Frage, was denn der Wert ist.

        Bei undefined, null, Zahlen und Booleans ist es der primitive Wert, an dem du nichts ändern kannst.

        Ein String wird als Verweis auf das interne String-Objekt übergeben. Das ist aber unveränderlich, deswegen kannst du es als primitiven Wert ansehen.

        Alles andere sind Objekte und du bekommst einen Verweis auf das Objekt. Das heißt: du kannst den Inhalt des Objekts ändern, so weit es das zulässt, aber du kannst dem Aufrufer kein anderes Objekt unterschieben.

        Dafür bräuchte es echte Referenzparameter, wie bspw. in PHP durch das & Zeichen.

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Hallo Rolf,

          Danke für Deine Information. Das hilft mir weiter.

          Gruß Effel

          1. Hallo effel,

            guck mal hier im Wiki, Abschnitt 2.2.2 Parameterbindung.

            Das habe ich eben eingebaut. Findest Du das für Dich verständlich?

            Rolf

            --
            sumpsi - posui - obstruxi
  2. Hallo effel,

    zunächst einmal: Code ist deutlich besser lesbar, wenn man ihn passend einrückt. Und hier im Forum hilft es dann noch, wenn man JavaScript-Code nicht einfach mit ~~~ einleitet, sondern mit ~~~js. Dann weiß der Codeformatierer, dass er den Syntax-Highlighter für JavaScript aktivieren muss.

    Weitere Helfer sind:

    • Leerstellen

    • Zusammenfassen von Deklaration und Initialisierung

    • Keine unnötige Initialisierung (bei anzx), die gleich wieder überschrieben wird

    • Bei Namen, die zusammengesetzt sind, helfen BinnenMajuskeln bei der Lesbarkeit.

    • Variablennamen sollten aussagen, was sich darin befindent. z0, z1, z2, arg1, arg2 - das ist unlesbares Kauderwelsch. Dein drei Monate älteres Ich wird Dich dafür hassen.

    • Dass man heute var eher vermeidet und let verwendet, ist ein Detail.

    • Wenn ich das richtig sehe, ist anzX eine Kopie von arg1. Du erzeugst ein leeres Array und kettest den Inhalt von arg1 daran. Das geht aber einfacher, wenn Du die slice-Methode verwendest. Mit array.slice(start, end) kopierst Du die Arrayeinträge von Index start bis end. Lässt man start und end weg, kopiert die Funktion alles. Alternativ kannst Du auch den Spread-Operator ... verwenden: anzX = [... arg1]

    • Aber: Du änderst nichts an arg1 oder an anzX. Das Anfertigen einer Kopie ist daher unnötig.

    • Es ist sinnlos, einen Wert als Parameter zu übergeben (arg3), wenn man ihn innerhalb der Funktion dann gleich überschreibt (du setzt arg3 auf 0 bevor Du es verwendest)

    • Du verwendest z1 und z2, um Werte an anzX01 und anzX02 anzuhängen. Das geht einfacher mit der push-Methode: anzX01.push(korr005(anzX[z0])). Kein z1 nötig.

    • Du programmierst eine while-Schleife um einen Zähler von 0 bis "< anzX.length" zu realisieren. Das geht in erster Näherung einfacher mit einer for(;;)-Schleife, und in zweiter Näherung gibt's auch for..of. Alle relevanten Browser können das (der IE nicht, aber der ist seit ein paar Monaten irrelevant).

    • Du benutzt arg3 als Index für die Ausgabe. Wenn Du etwas zugewiesen hast, setzt Du arg3 um 1 hoch. Dafür ist der Post-Inkrement Operator ++ nützlich. Er erhöht die Variable und gibt den Wert vor der Erhöhung zurück.

      // Speichere y an Position pos und erhöhe pos danach um 1 x[pos++] = y;

    • Warum ist es Dir wichtig, das Ergebnis in ein Array zu schreiben, das Du als Parameter übergibst? Du erzeugst - je nach Inhalt von arg1 - null bis zwei Ergebnisarrays, die auf den Positionen 0 und 1 von m16a gespeichert werden. Du weißt aber nicht, ob auf Position 0 die korr005-Werte für die geraden oder ungeraden Werte in anz_1 stehen, weil Du ja anzX01 und anzX02 nur speicherst - und nur dann den Index hochsetzt - wenn mindestens ein Wert drinsteht. Ist das für Dich sinnvoll?

    Meine erste Überarbeitung der Funktion würde so aussehen:

    Aufruf: /*m16a=*/ trennen1(anz_1,m16a); //ergeb in m16.. gespeichert 
    
    function trennen1(werte, resultate) {
       let anzGerade = [],
           anzUngerade = [];
    
       for (let wert of arg1) {
          if (wert % 2 == 0)
             anzGerade.push(korr005(wert));
          else
             anzUngerade.push(korr005(wert));
       }
    
       let resultatPos = 0;  
    
       if (anzGerade.length > 0) {
          resultate[resultatPos++] = anzGerade;
       }
       if (anzUngerade.length > 0) {
          resultate[resultatPos++] = anzUngerade;
       }
    }
    

    Man könnte statt for..of auch die forEach-Methode verwenden, das bringt aber nach meinem Dafürhalten keinen Mehrwert. Und statt eines if könnte man den ternären Operator nutzen,um das Zielarray für push auszuwählen - das macht es aber aus meiner Sicht schlechter lesbar. Oder wie gefiele Dir dies:

       for (let wert of arg1) {
          (wert % 2 == 0 ? anzGerade : anzUngerade).push(korr005(wert));
       }
    

    oder gar

       arg1.forEach(wert => (wert % 2 ? anzUngerade : anzGerade).push(korr005(wert));
    

    Ich finde das erste grenzwertig und das zweite scheußlich 😉

    Aber hattest Du nun eigentlich eine Frage? Oder wolltest Du deinen Code einfach vorstellen? Was wäre deine Erwartungshaltung dazu?

    Rolf

    --
    sumpsi - posui - obstruxi
    1. arg1.forEach(wert => (wert % 2 ? anzUngerade : anzGerade).push(korr005(wert));
      

      Ich finde das erste grenzwertig und das zweite scheußlich 😉

      Das Dritte finde ich „scheußlich“.

      1. Eine zu lange Zeile.
      2. Jeder weiß, dass ich in Ganzgenauheim sozialisiert wurde. Deshalb zähle ich gerne bestimmte Zeichen:
      
      function Zeichenzähler( haystack, needels=false, log=false ) {
      	if ( false == needels ) {
      		needels = haystack;
      	}
      	if ( 'string' == typeof needels ) {
      		needels = needels.split('');
      	}
      	var zähler={};
      	for (var i=0; i < needels.length; i++) {
      		zähler[needels[i]] = 0;
      	}
      	needels = Object.keys(zähler);
      	needels.sort();
      	haystack.split('').forEach( 
      		function ( item, index, arr ) {
      			for ( i=0; i <= needels.length; i++ ) {
      				if( item == needels[i] ) {
      					zähler[needels[i]]++;
      				}
      			}
      		}
      	);
      	
      	if ( log ) {
      		for ( i=0; i < needels.length; i++ ) {
      			console.log( 
      			console.log( 
      				'Zeichen »' 
      				+ needels[i] 
      				+ '« : ' 
      				+  zähler[needels[i]] 
      				+ ' * gefunden.'
      			);
      		}
      	}
      	return zähler;
      }
      
      str = 'arg1.forEach(wert => (wert % 2 ? anzUngerade : anzGerade).push(korr005(wert));';
      Zeichenzähler( str, '()[]{}\'"', true );
      
      
      Zeichen »"« : 0 * gefunden.
      Zeichen »'« : 0 * gefunden.
      Zeichen »(« : 4 * gefunden.
      Zeichen »)« : 3 * gefunden.
      Zeichen »[« : 0 * gefunden.
      Zeichen »]« : 0 * gefunden.
      Zeichen »{« : 0 * gefunden.
      Zeichen »}« : 0 * gefunden.
      

      😱

      1. Hallo,

        1. Jeder weiß, dass ich in Ganzgenauheim sozialisiert wurde. Deshalb zähle ich gerne bestimmte Zeichen:
        
        function Zeichenzähler( haystack, needels=false, log=false ) {
        	if ( false == needels ) {
        		needels = haystack;
        . . . 
        

        Meinereiner ist zumindest zeitweise in Overcarefullington sozialisiert worden und möchte auf die richtige Schreibweise der needles hinweisen…

        Gruß
        Kalk

        1. Meinereiner ist zumindest zeitweise in Overcarefullington sozialisiert worden und möchte auf die richtige Schreibweise der needles hinweisen…

          Das ist schnell nachgebessert. Außerdem habe ich mir die Frechheit erlaubt, bei mir nicht gefallenden Daten ein paar Ausnahmen zu schmeißen.

          function CharCounter( haystack, needles=false, log=false ) {
          	var counter={};
          	if (	
          		   null  === needles
          		|| false === needles
          		|| true  === needles
          		|| ''     == needles
          	) {
          		throw( 'Error: needles is exact null, true, false - or empty' ) ; 
          	}
          	
          	if ( 'string' == typeof needles ) {
          		needles = needles.split('');
          	}	
              
          	if ( ! Array.isArray( needles )  ) {
          		needles[0] = needles;
          	}
          	
          	for ( var i=0; i < needles.length; i++ ) {
          		if ( 'string' == typeof needles[i] ) {
          			if ( 1 < needles[i].length ) {
          				throw('Error: String with length > 1 in array needles[' + i + ']: ' + JSON.stringify( needles[i] ) ) ; 
          			} else if ( 1 == needles[i].length ) {
          				counter[needles[i]] = 0;
          			} else {
          				console.warn( 'Warníng: Empty string-element in array needles at position ' + i + ' ignored.' );
          			}
          		} else {
          			throw( 'Error: Element at position ' + i + ' in array needles is not of type string: It is a ' + typeof( needles[i] ) + '. Value(s): '+ JSON.stringify( needles[i] ) );
          		}
          	}
          	needles = Object.keys(counter);
          	needles.sort();
          	haystack.split('').forEach( 
          		function ( item, index, arr ) {
          			for ( var i = 0; i <= needles.length; i++ ) {
          				if( item == needles[i] ) {
          					counter[needles[i]]++;
          				}
          			}
          		}
          	);
          	
          	if ( log ) {
          		for ( i=0; i < needles.length; i++ ) {
          			console.log( 
          				'Char »' 
          				+ needles[i] 
          				+ '« has ' 
          				+ counter[needles[i]] 
          				+ ' founds.'
          			);
          		}
          	}
          	return counter;
          }
          
          str = 'arg1.forEach(wert => (wert % 2 ? anzUngerade : anzGerade).push(korr005(wert));';
          
          CharCounter( str, '()', true );
          
          /////////////////// Tests: /////////////////////////////////////////////////////////////////
          //CharCounter( str, '()[]{}\'"', true );            /* Fine */
          //CharCounter( str, str , true );                   /* Fine: Count all Chars in haystack  */
          //CharCounter( str, [' ',''] , true );              /* Fine with warning */
          //CharCounter( str, null , true );                  /* Error */
          //CharCounter( str, true , true );                  /* Error */
          //CharCounter( str, ['(', null ] , true );          /* Error */
          //CharCounter( str, [' ', 100.8 ], true );          /* Error */
          //CharCounter( str, [ ' ', [ 'f','c' ] ], true );   /* Error */
          

          Ausgabe:

          Char »(« has 4 founds.
          Char »)« has 3 founds.
          

          Wichtiger wäre die Frage, warum ich die Klammern zähle...

          1. Hallo Raketenwilli,

            nach meiner Grundsozialisierung in Vomhirninsgerätingen hatte ich noch eine Fortbildung in Cleanercodenhausen...

            • Ich würde needles nicht false als Defaultparameter geben. Lässt man diesen Parameter vortümlich oder irrsätzlich weg, kriegt man auf die Finger, weil der Parameter false sei. Besser fände ich
               if (arguments.length < 2) {
                  throw new Error("CharCounter needs haystack and needles to do something useful");
               }
               if ('string' !== typeof haystack) {
                  throw new Error("Haystack must be a string");
               }
               // alternativ
               if (!haystack || !(haystack.split instanceof Function)) {
                  throw new Error("Haystack must be splittable");
               }
            
            • Dein Hantieren mit Counter und Needles finde ich ebenfalls unnötig kompliziert. Du erwartest für die needles einen String mit den zu prüfenden Zeichen, oder ein Array aus den zu prüfenden Zeichen. Werriwell. Aber du machst es Dir dann äußerst schwer, das zu validieren. Mit verwirrenden Fehlermeldungen. Wenn ich Dir eine Zahl übergebe, maulst Du, dass an Position 0 im Array needles kein String stünde.

            Warum nicht so:

               if ('string' == typeof needles) {
                  needles = needles.split('');
               }
               else if (Array.isArray(needles)) {
                  if (!needles.every(needle => ('string' == typeof needle) &&
                                              (needle.length == 1))) {
                     throw new Error("Needle array must contain only strings of length 1");
                  }
               }
               else {
                  throw new Error("Needles must be a string or an array of characters");
               }
            

            Okay, das Ignorieren von Nadeln der Länge 0 fehlt. Das Initialisieren des counter-Arrays wäre dann der Folgeschritt.

            Das Sortieren der Nadeln würde ich weglassen. Grund: die Zeichen (), {} und [] sind im Unicode paarweise beieinander. Aber vielleicht möchte jemand eine spezifische Reihenfolge. Oder in irgendeiner Fremdsprache sind die Zeichen, die Pärchen bilden, nicht so schön als Codepoints angeordnet. Ich würde die Nadeln genau in der Reihenfolge belassen, in der sie übergeben werden und es ein Feature nennen. Wer eine bestimmte Reihenfolge will, soll sie vorsortieren. DOT[1].

            Im Sinne des DOT-Prinzips könnte man sogar darüber nachdenken, die Schnittstelle der Funktion zu verschlanken und die Überladung von needles mit string und Array wegzulassen. Lass als needles nur einen String zu. Wer ein Array hat, soll es flugs joinen, das ist nicht viel Arbeit.

            <denk>Man KÖNNTE es aber auch so machen, dass man haystack und needles nicht auf string prüft, sondern ein iterierbares Objekt erwartet. Das kann man bspw. mit if (needles[Symbol.iterator]) testen. Die Strafe dafür ist dann, dass man jeden Wert der Iteration darauf prüfen muss, ob er ein String der Länge 1 ist. Hm. Nö. Gefällt mir nicht.</denk>

            Wenn needles ein String sind, kannst Du mit indexOf schauen, ob das aktuelle Zeichen in haystack eins ist, das Du zählen möchstest. Aber - LOL - wenn sie ein Array sind, geht das genauso. Aber Du sparst Dir die Analyse auf einen String aus einem Zeichen pro Arrayeintrag. Das würde ich als Problem Anderer Leute deklarieren.

            Den haystack mit split('').foreach(...) zu durchlaufen - kann man machen. Aber man könnte auch die for..of Schleife nutzen - der IE ist schließlich zu glorreicher Irrelevanz erhoben worden…

            Für die log-Schleife (deren Existenz ebenfalls auf dem DOT-Altar geopfert werden sollte), bietet sich dann noch ein Template-String in Backticks an.

               let counter = {};
               for (let pin of needles) {
                  counter[pin] = 0;
               }
            
               for (let straw of haystack) {
                  if (needles.indexOf(straw) >= 0) {
                     counter[straw]++;
                  }
               }
            
               if (log) {
                  for (let pin of needles) {
                     console.log(`Char »${pin}« occurs ${counter[pin]} times`);
                  }
               }
            

            Die Idee mit dem Iterator sähe so aus:

               if (!(haystack[Symbol.iterator] instanceof Function) ||
                   !(needles[Symbol.iterator] instanceof Function)) {
                  throw new Error("haystack and needles must be iterable");
               }
               let counter = {};
               for (let pin of needles) {
                  if ('string' != typeof pin || pin.length != 1) {
                     throw new Error(...);
                  }
                  counter[pin] = 0;
               }
               for (let straw of haystack) {
                  if ('string' != typeof pin || pin.length != 1) {
                     throw new Error(...);
                  }
                  let c = counter[straw];
                  if (c != undefined)
                     counter[straw] = c+1;
                  }
               }
            

            Aber diese Prüfungen dürften Laufzeitstrafe bringen. Deswegen schmeckt mir das nicht so. Es sei denn, man definiert das als Feature - und sagt: Das ist ein generischer Counter. Wer in haystack und needles etwas drin hat, was kein String der Länge 1 ist - na gut, der zählt dann halt das. Und damit sind die Prüfungen nicht nur unnötig, sondern sogar störend.

            Rolf

            --
            sumpsi - posui - obstruxi

            1. Do One Thing ↩︎

            1. (Eigentlich ging es ja um die Anzahl der Klammern in Deinem scriptlet …)

              "use strict";
              
              function CharCounter( haystack, needles, log ) {
              
              	/* CharCounter() count chars in a string grouped by char.
              	 * * Args
              	 * 	- Arg #1: var haystack:
              	 * 		Must set.
              	 * 		The string.
              	 * 
              	 * 	- Optional arg #2: var needles:
              	 * 		A string or array with the chars which will be grouped and count.
              	 * 		If it is not set, all occurring(sic!) characters in haystack are counted.
              	 * 
              	 * 	- Optional arg #2: var log:
              	 * 		Truly or falsy: Shows the result (sorted) in the console?
              	 * 
              	 * 	- vars from parent envirement:
              	 * 	 -  optional: var CharCounterLogDefault 
              	 * 			This is a option (must not defined): true or false
              	 *			The arg #3 overwrite this. If never set the value is false
              	 * 
              	 * * Returns a object a.k.a. { a:1,o:2,'3':1 } 
              	 *   Object.keys are grouped but not sorted.
              	*/
              
              	if( typeof log == 'undefined') {
              		if( typeof CharCounterLogDefault != 'undefined' ) {
              			log = CharCounterLogDefault;
              		} else {
              			log = false;
              		}
              	} 
              
              	if( arguments.length < 1 ) {
              		throw new Error( 
              			'CharCounter has 3 args:'  + "\n"
              		+ 	'- haystack(type: string),' + "\n"
              		+   '- needles(string or array).' + "\n"
              		+   'If needles not given it count all chars in haystack.' + "\n"
              		+   'The last arg is log (truly or falsy). If truely CharCounter' + "\n"
              		+	'print into the console.'
              		);
              	}
              	
              	if( 'string' != typeof haystack ) {
              		throw new Error('Argument 1 (haystack) is not astring!');
              	}	
              	
              	if( arguments.length == 1 ) {
              		needles = haystack;
              	}	
              
              	var counter = {};
              
              	if(	
              		   null  === needles
              		|| false === needles
              		|| true  === needles
              		|| ''     == needles
              	) {
              		throw new Error( 'Error: needles is exact null, true, false - or empty' ) ; 
              	}
              
              	if( 'string' == typeof needles ) {
              		needles = needles.split('');
              	}	
                  
              	if( ! Array.isArray( needles )  ) {
              		needles[0] = needles;
              	}
              	
              	for( let element of needles ) {
              		if( 'string' == typeof element ) {
              			if( 1 < element.length ) {
              				throw new Error('Error: String with length > 1 in array needles[]: ' + JSON.stringify( element ) ) ; 
              			} else if( 1 == element.length ) {
              				counter[element] = 0;
              			} else {
              				console.warn( 'Warníng: Empty string-element in array needles[] ' + JSON.stringify( element ) + ' ignored.' );
              			}
              		} else {
              			throw new Error( 'Error: Element in array needles ( ' + JSON.stringify( element ) + ' ) is not of type string: It is a ' + typeof element + '.');
              		}
              	}	
              	
              	needles = Object.keys(counter);
              	haystack.split('').forEach( 
              		function( item, index, arr ) {
              			for( let char of needles ) {
              				if( item == char ) {
              					counter[char]++;
              				}
              			}
              		}
              	);
              	
              	if( log ) {
              		for( let char of needles.sort() ) {
              			console.log( 
              				'Char »' 
              				+ ReplaceInvisibleChars( char )
              				+ '« has ' 
              				+ counter[char] 
              				+ ' founds.'
              			);
              		}
              	}
              	return counter;
              }
              
              function ReplaceInvisibleChars( s ) {
              	return s.replace( /\u0000/g, '[NULL]' )
              		.replace( /\u0001/g, '[START OF HEADING]' )
              		.replace( /\u0002/g, '[START OF TEXT]' )
              		.replace( /\u0003/g, '[END OF TEXT]' )
              		.replace( /\u0004/g, '[END OF TRANSMISSION]' )
              		.replace( /\u0005/g, '[ENQUIRY]' )
              		.replace( /\u0006/g, '[ACKNOWLEDGE]' )
              		.replace( /\u0007/g, '[ALERT]' )
              		.replace( /\u0008/g, '[BACKSPACE]' )
              		.replace( /\u0009/g, '[HORIZONTAL TABULATION]' )
              		.replace( /\u000A/g, '[LINE FEED]' )
              		.replace( /\u000B/g, '[VERTICAL TABULATION]' )
              		.replace( /\u000C/g, '[FORM FEED]' )
              		.replace( /\u000D/g, '[CARRIAGE RETURN]' )
              		.replace( /\u000E/g, '[SHIFT OUT]' )
              		.replace( /\u000F/g, '[SHIFT IN]' )
              		.replace( /\u0010/g, '[DATA LINK ESCAPE]' )
              		.replace( /\u0011/g, '[DEVICE CONTROL 1]' )
              		.replace( /\u0012/g, '[DEVICE CONTROL 2]' )
              		.replace( /\u0013/g, '[DEVICE CONTROL 3]' )
              		.replace( /\u0014/g, '[DEVICE CONTROL 4]' )
              		.replace( /\u0015/g, '[NEGATIVE ACKNOWLEDGE]' )
              		.replace( /\u0016/g, '[SYNCHRONOUS IDLE]' )
              		.replace( /\u0017/g, '[END OF TRANSMISSION BLOCK]' )
              		.replace( /\u0018/g, '[CANCEL]' )
              		.replace( /\u0019/g, '[END OF MEDIUM]' )
              		.replace( /\u001A/g, '[SUBSTITUTE]' )
              		.replace( /\u001B/g, '[ESCAPE]' )
              		.replace( /\u001C/g, '[FILE SEPARATOR]' )
              		.replace( /\u001D/g, '[GROUP SEPARATOR]' )
              		.replace( /\u001E/g, '[RECORD SEPARATOR]' )
              		.replace( /\u001F/g, '[UNIT SEPARATOR]' )
              		.replace( /\u0085/g, '[NEXT_LINE]' )
              		.replace( /\u2028/g, '[LINE_SEPARATOR]' )
              		.replace( /\u2029/g, '[PARAGRAPH_SEPARATOR' )
              	;	
              }
              
              
              
              /*
               *  Tests:
              */
              
              /*optional*/ var CharCounterLogDefault = true; // or false
              var str = 'Test: ' + "\u0000\n" + "\x0A" + 'arg1.forEach(wert =>' + "\t" + '*(wert % 2 ? anzUngerade : anzGerade).push(korr005(wert));';
              
              CharCounter( str );
              
              //CharCounter( str, '()[]{}\'"', true );            /* Fine */
              //CharCounter( str, [ "\n", "\t", '(', ')' ], true );          /* Fine */
              //CharCounter( str, str , true );                   /* Fine: Count all chars in haystack  */
              //console.log( CharCounter( str, str , false ) );   /* Fine: Count all chars in haystack, write nothing  */
              //CharCounter( str, [' ',''] , true );              /* Fine with warning */
              //CharCounter( str, null , true );                  /* Error */
              //CharCounter( str, true , true );                  /* Error */
              //CharCounter( str, ['(', null ] , true );          /* Error */
              //CharCounter( str, [' ', 100.8 ], true );          /* Error */
              //CharCounter( str, [ ' ', [ 'f','c' ] ], true );   /* Error */
              

              Log-Output mit dem aktiviertem Test:

              Char »[NULL]« has 1 founds.
              Char »[HORIZONTAL TABULATION]« has 1 founds.
              Char »[LINE FEED]« has 2 founds.
              Char » « has 8 founds.
              Char »%« has 1 founds.
              Char »(« has 4 founds […]
              

              Ich würde needles nicht false als Defaultparameter geben.

              Ja. Das war ein Rest einer früheren Variante.

              Dein Hantieren mit Counter und Needles finde ich ebenfalls unnötig kompliziert. Du erwartest für die needles einen String mit den zu prüfenden Zeichen, oder ein Array aus den zu prüfenden Zeichen. Werriwell.

              • Willichaberso!

              Aber du machst es Dir dann äußerst schwer, das zu validieren. Mit verwirrenden Fehlermeldungen. Wenn ich Dir eine Zahl übergebe, maulst Du, dass an Position 0 im Array needles kein String stünde.

              • Leicht geändert.

              Das Sortieren der Nadeln würde ich weglassen.

              • Geändert. Wird nur noch für die Debug-Ausgabe gemacht. Dort ist es nützlich, geb ich das Objekt (a.k.a. „hash“, „array with named keys“) zurück, dann ist war es nur ein Zeitfresser. Will der Verwender das sortieren: Das Rezept steht ja in der Funktion und einen Kopf hat er selbst…

              Für die log-Schleife (deren Existenz ebenfalls auf dem DOT-Altar geopfert werden sollte),

              Die ist fast der eigentliche Sinn der Sache … gelassen und schwer verbessert. Habe nur für die „Logausgabe“ eine kleine Universal-Funktion (ReplaceInvisibleChars()) zur lesbaren Ausgabe der „nicht druckbaren“ Zeichen hinzugefügt und benutzt. Nicht über die „gar nicht vorkommenden könnenden Zeichen“ wundern: nodejs könnte ja aus allerhand Quellen lesen…

        2. @@Tabellenkalk

          Meinereiner ist zumindest zeitweise in Overcarefullington sozialisiert worden und möchte auf die richtige Schreibweise der needles hinweisen…

          Needless to say. 🤪

          🖖 Живіть довго і процвітайте

          --
          When the power of love overcomes the love of power the world will know peace.
          — Jimi Hendrix
      2. Hallo Raketenwilli,

        da ich ein Vomhirninsgerätinger bin, sind unpaarige Klammern etwas, dessen Auffindung ich höheren Instanzen überlasse. Also zum Beispiel einem Kasseler im Schloss. Oder andersrum... 😉. Oder der JS Engine:

        str = 'arg1.forEach(wert => (wert % 2 ? anzUngerade : anzGerade).push(korr005(wert));';
        try {
           f = new Function(str);
        }
        catch(err) {
           console.log(err);
        }
        
        SyntaxError: missing ) after argument list
            at new Function (<anonymous>)
        

        Leeiiiiider ist diese Methode nicht vorbehaltlos nutzbar. Wenn ich das nämlich in einem DevTools-Fenster mache, das ich aus dem Forum heraus geöffnet habe, dann erhalte ich

        EvalError: Refused to evaluate a string as JavaScript because
        'unsafe-eval' is not an allowed source of script in the following
        Content Security Policy directive: "script-src 'self'
        'nonce-eJ0aztS3SR0o0dGWAdjJLRzTun-3ROvbzXIHTIclDsU' *.selfhtml.org".
        

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Hallo Rolf,

          Also zum Beispiel einem Kasseler im Schloss. Oder andersrum... 😉.

          ist das jetzt ein Wortspiel mit Kassel und Castle?
          Oder ist das ein Insider, den ich nicht kenne?

          Einen schönen Tag noch
           Martin

          --
          Die Wissenschaft hat festgestellt, dass der Arsch die Beine hält.
          Und die Beine, die sind so gestellt, dass der Arsch nicht runterfällt.
          1. Hallo Martin,

            ja, Insider. Aber Du solltest den verstehen.

            Rolf

            --
            sumpsi - posui - obstruxi
            1. Hi,

              ja, Insider. Aber Du solltest den verstehen.

              okay, ich glaube zu verstehen. Aber dann ist der Kalauer sehr platt.
              Könnte man fast unter der Tür durchschieben.

              Einen schönen Tag noch
               Martin

              --
              Zucker ist das Zeug, das den Kaffee bitter macht, wenn man es weglässt.
              1. Hi,

                ja, Insider. Aber Du solltest den verstehen.

                okay, ich glaube zu verstehen. Aber dann ist der Kalauer sehr platt.
                Könnte man fast unter der Tür durchschieben.

                Ich kann gar nicht sauer sein, weil ich ja selbst damit „spiele“. Und das in sogar sehr böser Absicht gegenüber bitterbösen Leuten, die sich für „geistig überlegen“ halten…

              2. @@Der Martin

                Könnte man fast unter der Tür durchschieben.

                Was sich so unter der Tür durchschiebt

                🖖 Живіть довго і процвітайте

                --
                When the power of love overcomes the love of power the world will know peace.
                — Jimi Hendrix
                1. Was sich so unter der Tür durchschiebt

                  Um da durchzukommen muss man sehr genau saufen können…

    2.    arg1.forEach(wert => (wert % 2 ? anzUngerade : anzGerade).push(korr005(wert));
      

      Ich finde das erste grenzwertig und das zweite scheußlich 😉

      Die dritte (von mir stehen gelassene) Variante wäre demnach „toll“? Das bedarf aber einer Korrektur (die Zahl der Klammern stimmt nicht...) und einer Kommentierung, weil nicht leicht ersichtlich ist, warum das funktioniert. Außerdem bedarf sowas eines anschaulichen Tests, der die Funktion zeigt:

      "use strict";
      
      /* Nur zum Verschönern der Ausgabe: */
      function humanVisible( v ) {
      	return JSON.stringify( v )
      		.replace( /,/g, ' , ')
      		.replace( /\[/g, '[ ' )
      		.replace( /\]/g, ' ]' )
      		.replace( /\{/g, '{ ' )
      		.replace( /\}/g, ' }' )
      	;
      }
      
      /* Naja. Die Funktion, welche die Werte verändert */ 
      function korrekturFunktion( v ) {
      	return ( v * 1.1 );
      }
      
      /* Ladys & Gentlemen! Es folgen die Werte in einem Array */
      var arr = [0,1,2,3,4,5];
      
      /* use strict erfordert eine Deklaration */
      var arrG = [];
      var arrU = [];
      
      /* Was das tut:
       * Für jedes Element des Arrays arr als Variable item
       * 		WENN item % 2 „truly“ (e.g. != 0 ) ist,
       * 			DANN füge dem Array „arrU“ den korrigierten Wert hinzu,
       * 			SONST füge „arrG“ den korrigierten Wert hinzu,
       * 
      */
      arr.forEach(
      	item => ( item % 2 )
      		? arrU.push( korrekturFunktion( item ) )
      		: arrG.push( korrekturFunktion( item ) )  
      );
      /* Hint(0):
       * 	Man kann das also schöner als in einer Zeile notieren.
       * 
       * Hint(1):
       * 	Die Variable item ist danach nicht mehr definiert.
       * 
       * Hint(2):
       * 	Es wird ausgenutzt, dass in der Array-Methode arr.forEach 
       * 	Variablen in der „übergeordneten Umgebung“ (a.k.a. scope,
       * 	hier „arrG“ und “arrU“) überschrieben werden können.
       *
       * Letzteres halte ich für einen „Hirnfurz“ der Konstrukteure von JS
      */
      
      /* „Schöne“ Ausgaben */
      console.log( 
      		"Array korrigierter gerader Zahlen:\n\t"
      	+  	humanVisible( arrG ) 
      	+	"\n\nArray korrigierter ungerader Zahlen:\n\t"
      	+	humanVisible( arrU )
      );
      
      /* 
       * Ausgaben:
      /*
      Array korrigierter gerader Zahlen:
      	[ 0 , 2.2 , 4.4 ]
      
      Array korrigierter ungerader Zahlen:
      	[ 1.1 , 3.3000000000000003 , 5.5 ]
      
      * 
      * Der von mir erwähnte „Fehler“ durch die binäre
      * Speicherung ist in der zweiten Ausgabe sehr gut zu sehen
      */
      
    3. @@Rolf B

      Ich finde das erste grenzwertig und das zweite scheußlich 😉

      I’ve fixed it for you:

        arg1.forEach(
          wert => (
            wert % 2 ? anzUngerade : anzGerade
          ).push(korr005(wert)
        );
      

      🖖 Живіть довго і процвітайте

      --
      When the power of love overcomes the love of power the world will know peace.
      — Jimi Hendrix
      1. Hallo

        Ich finde das erste grenzwertig und das zweite scheußlich 😉

        I’ve fixed it for you:

          arg1.forEach(
            wert => (
              wert % 2 ? anzUngerade : anzGerade
            ).push(korr005(wert)
          );
        

        Dir fehlt auch eine schließende Klammer. 😅

        Zitat von dort herinnen:

        …
        Zeichen »(« : 4 * gefunden.
        Zeichen »)« : 3 * gefunden.
        …
        

        Tschö, Auge

        --
        200 ist das neue 35.