2017-05-03 2 views
2

Die Frage war, wenn mehrere Arrays ein Array mit allen geschnittenen Array-Werte zurückgeben. Ich habe ein paar Lösungen gelesen und versuche diese Hashtabelle zu verstehen.Javascript Hash-Tabelle Datenstruktur. Schnittpunkt und reduzieren

Ich habe Probleme, diese Linie zu verstehen:

a[propName] = a[propName] || {count:0, value: val}; 

Zu meinem Verständnis sind wir durch jedes Element unserer Sub-Array-Looping. Unser Akkumulatorobjekt erhält den Eigenschaftsnamen des Subarrays-Werts.

Hier ist ich verwirrt. Der Wert unserer Objekteigenschaft ist ein [propName]. Ich verstehe diesen Wert nicht. Mein Verständnis ist, dass wir unsere Objekteigenschaft zum Wert unseres Subarrays machen sollten (indem wir stattdessen die Zeile a[propName]=a[propName] in a[propName]=propName einfügen), aber wenn ich dies tue, können wir nicht zählen, wie oft die Eigenschaft aufgetreten ist. Ich verstehe nicht, warum wir die a[propName] setzen müssen und auf welche Datenstruktur wir zugreifen, die sich von der Verwendung von propName unterscheidet. Es gibt offensichtlich einen Unterschied, seit wann ich a[propName] verwende, können wir zählen, wie oft die Eigenschaft aufgetreten ist. Wenn jemand gründlich erklären kann, was vor sich geht, wäre ich sehr dankbar.

function intersection(){ 
    // convert arguments to array of arrays 
    var arrays = [].slice.call(arguments); 
    // create an object that tracks counts of instances and is type specific 
    // so numbers and strings would not be counted as same 
    var counts= arrays.reduce(function(a,c){ 
    // iterate sub array and count element instances 
    c.forEach(function(val){ 
     var propName = typeof val + '|' + val; 
     // if array value not previously encountered add a new property   
     a[propName] = a[propName] || {count:0, value: val};  
     // increment count for that property 
     a[propName].count++; 
     console.log(a); 
    }); 
    return a; 
    },{}); 

    // iterate above object to return array of values where count matches total arrays length 
    return Object.keys(counts).reduce(function(resArr, propName){ 
    if(counts[propName].count === arrays.length){ 
     resArr.push(counts[propName].value); 
    } 
    return resArr; 
    },[]); 

} 

Antwort

1

Die Linie, die Sie prüft, weisen, wenn a[propName] vorhanden ist, und, wenn es existiert nicht (so ist es undefined) initialisieren es {count:0, value: val};.

Schauen wir uns das genauer an.

Zuallererst verwenden wir sinnvollere Namen. a ist accumulator, die Variable, die Sie verwenden, um alles im Auge zu behalten.

Am Anfang ist es ein leeres Objekt.

In der ersten Iteration von c.forEach hat es keine Eigenschaften.

Daher wird bei einem propName wie 'string | asd' die erste Eigenschaft hinzugefügt und accumulator wird accumulator = {'string|asd' : {count:0, value: val}};.

Dann wird der Zählwert erhöht.

Wenn es eine andere 'Zeichenfolge | asd' findet, erhöht es nur die Zählung, weil die Prüfung a[propName] = a[propName] || {count:0, value: val}; nur die prop halten wird.

let a = {} 
 

 
// a.c does not exist, therefore is undefined 
 
console.log(a.c) 
 

 
a.c = a.b || 1; 
 
// a.c now is 1 
 
console.log(a.c) 
 

 
a.c = a.c || 2; 
 
// a.c is still 1, because the `or` operator returns as soon as it finds a valid value 
 
console.log(a.c)

+2

Beachten Sie, dass, wenn 'a [propName]' bereits vorhanden ist und gleich 0, null, oder irgendetwas anderes [ "falsy"] (https://developer.mozilla.org/ en-US/docs/Glossar/Falsy), wird es auch durch dieses Objekt ersetzt. Das könnte gut sein, aber es ist nicht unbedingt eine Existenzprüfung. Sie könnten 'a [propName] = (propName in a) || verwenden {count: 0, value: val}; 'wenn das Original nicht das gewünschte Verhalten war. –

+0

@MikeMcCaughan Im Kontext dieser Anwendung ist es eine Invariante, dass, wenn 'a [propName]' existiert, es immer ein Objekt sein wird. Der Code muss sich also nicht darum kümmern, dass er ein anderer falscher Wert ist. – Barmar

+0

@Barmar Natürlich, aber da der Fragesteller ein Anfänger ist, war es wichtig zu erklären, dass die Verwendung von 'obj [propName]' zur Überprüfung der Existenz * im Allgemeinen * nicht ausreichend ist. –