Holger: Key-Value-Pair mit höchster Value ernten

Hallo,

ich versuche gerade aus einem Objekt das Key-Value-Pair mit der höchsten Value zu ernten und versteh nicht ganz warum ich scheitere...

var Werte = {Wert1: 1, Wert2: 2};


var hoechster_Wert = Object.keys(Werte).reduce(function(a, b) {
		if (!a) { // noch kein a vorhanden? aktueller Wert als Ausgangspunkt
			a[b] = Werte[b];
		}
			if (Werte[b] > Werte[a]) {
			a[b] = Werte[b]; // höchster Wert überschreibt a[b]
		}
		return a;
}, {});

/*

+++ GEWÜNSCHTER OUTPUT: hoechster_Wert = {Wert2: 2} +++

*/

Leider wird mir nur ein leeres Objekt ausgespuckt... warum?

Danke!

  1. Hallo,

    ich versuche gerade aus einem Objekt das Key-Value-Pair mit der höchsten Value

    das Vergleichs Kriterium wäre zu definieren: Kopf oder Zahl!?

    zu ernten und versteh nicht ganz warum ich scheitere...

    Am Vergleich vielleicht? Auf jeden Fall wäre Zahl mit Zahl zu vergleichen: Von Objekt zu Objekt. Und zwar über ein (temporäres) Array mit den Vergleichskriterien.

    Mfg

  2. Hallo Holger

    ich versuche gerade aus einem Objekt das Key-Value-Pair mit der höchsten Value zu ernten und versteh nicht ganz warum ich scheitere...

    var Werte = {Wert1: 1, Wert2: 2};
    
    
    var hoechster_Wert = Object.keys(Werte).reduce(function(a, b) {
    		if (!a) { // noch kein a vorhanden? aktueller Wert als Ausgangspunkt
    			a[b] = Werte[b];
    		}
    			if (Werte[b] > Werte[a]) {
    			a[b] = Werte[b]; // höchster Wert überschreibt a[b]
    		}
    		return a;
    }, {});
    

    Leider wird mir nur ein leeres Objekt ausgespuckt... warum?

    Du übergibst als Initialwert für den Akkumulator ein leeres Objekt an die Methode reduce und ein Objekt evaluiert in einem booleschen Kontext immer zu true. Das bedeutet, die erste Anweisung wird nie ausgeführt, weil die Bedingung nie erfüllt wird.

    Bei der zweiten bedingten Anweisung setzt du a, das immernoch ein Objekt ist, als Schlüssel für dein Objekt Werte ein. Schlüssel für Objekte müssen aber entweder vom Datentyp String oder vom Datentyp Symbol sein.

    Die Konsequenz deiner Handlung ist, dass die Methode toString des Objekts aufgerufen und deren Rückgabewert, der String [object Object], als Eigenschaftsname verwendet wird. Eine Eigenschaft mit diesem Namen existiert in dem Objekt Werte aber nicht. Also wird beim Zugriff der Wert undefined zurückgegeben.

    Für undefined ist keine Ordnung definiert, weshalb eine Prüfung mit ‚größer als‘ oder ‚kleiner als‘ immer false ergibt. Die zweite Anweisung wird also auch nicht ausgeführt und infolgedessen bei jedem Aufruf das als Initialwert übergebene Objekt zurückgegeben.

    Das ist dann auch der Rückgabewert der Methode reduce.

    Versuchs mal so:

    const object = {
        a: 1,
        b: 5,
        c: 2,
        d: 3
    };
    
    
    const key = Object.keys(object).reduce((a, b) => object[a] > object[b] ? a : b);
    
    
    const record = {
        [key]: object[key]
    };
    
    
    record; // {b: 5}
    

    Oder mit der Methode sort:

    const [key] = Object.keys(object).sort((a, b) => object[b] - object[a]);
    

    Viele Grüße,

    Orlok

    1. Hallo,

      danke für die sehr ausführliche Darstellung!

      Ich muss zu meiner Schande gestehen, dass ich beinahe schon mal so weit war (meine Definition von 'key' hat ursprünglich recht ähnlich ausgesehen) ...und ich dann am Zusammensetzen des Objekts gescheitert bin.

      Sah dann bei mir ungefähr so aus (münzt man's jetzt auf dein Beispiel um):

      
      const record = {
          key: object[key]
      };
      /* 
      retourniert natürlich 'key' als Objektschlüssel - aus unerfindlichen Gründen scheitere ich nun schon zum wiederholten Mal daran, mit [key] eine Variable als Schlüssel aufzurufen…
      */
      

      Von da an wurde es, wie von dir penibel aufgearbeitet, immer abenteuerlicher.

      Finde ich übrigens die eleganteste Methode um seiner Objektpärchen Herr zu werden. Bin auf StackOverflow auf einen anderen Zugang gestoßen, der dagegen ein wenig unbeholfen wirkt 😂

      StackOverflow - How to get the highest key and value from object

      Danke für deine Hilfe!

  3. Tach!

    Leider wird mir nur ein leeres Objekt ausgespuckt... warum?

    Mit Debugging könnte man der Ursache näher kommen. Der Block vom ersten if-Statement wird nicht ausgeführt. Objekte sind nie falsy, auch dann nicht wenn sie keine Eigenschaften haben.

    Ich würde das nicht auf diese Weise lösen und aus der Funktion heraus auf Werte im äußere Scope zugreifen, solange das nicht unbedingt nötig ist. Und das ist es in dem Fall auch nicht.

    Object.entries(Werte).reduce(function(a, b) {
    	return a[1] > b[1] ? a : b;
    }, []);
    

    Das Ergebnis ist allerdings kein Objekt sondern ein Array mit Key und Value der gesuchten Eigenschaft als Elemente. Und man muss hier auch nicht auf das initiale Objekt (oder in meinem Code ein Array) testen. Zugriffe auf nicht vohandene Elemente ergeben undefined, und das ist weder größer noch kleiner oder gleich dem Wert von b, so dass beim ersten Durchlauf das b zurückgeliefert wird.

    dedlfix.