2017-05-17 4 views
0

Ich bin neu in Javascript und mache ein paar Übungen, die ich online gefunden habe. Da ich wirklich verstehen will, wie die Dinge funktionieren und warum manche Ansätze besser sind als andere, würde ich mich über Feedback freuen, warum meine Ansätze schlecht (oder gut) sind.Zählen von Vorkommen von Werten in einem Array von Objekten

Ich habe ein XML und verarbeiten es mit dem SAX-Parser, um "trending keywords" zu erhalten. Als Gesamtergebnis sollte meine Funktion die 5 beliebtesten zurückgeben. Das Ergebnis meiner Analyse selbst ist ein Array mit 20 Objekten im Format

[{ 
    attributes: {} 
    //children is just one big entry, separated by ';' 
    children: ["Comey, James B;Federal Bureau of Investigation;Trump, Donald J;United States Politics and Government"] 
    IsSelfClosing: false, 
    name: 'ADX_KEYWORDS', 
    parent: null, 
    __proto__: {} 
}] 

Nun meine Idee war, diese children alle Werte und es

in einem neuen Array speichern, um herausziehen
let flattenArr = keywords.reduce((acc, cur) => acc.concat(cur.children), []); 

Als Ergebnis ich erhalte eine Anordnung (auch Länge 20) im Format

[["Comey, James B;Federal Bureau of Investigation;Trump, Donald J;United States Politics and Government"], 
["Trump, Donald J;Comey, James B;Federal Bureau of Investigation;United States Politics and Government"]] 

die einzelnen Werte zu verarbeiten, teilte ich das Array

let mapArr = flattenArr 
    .map(arr => arr.split(';')) 
    .reduce((acc, cur) => acc.concat(cur), []); 

und daher enthält das neue Array der Länge 115 jedes einzelne Schlüsselwort getrennt. Und hier ist der Punkt, an dem ich nicht weiß, wie ich vorgehen soll. Ich habe das Beispiel von MDN (Array.Reduce) versucht, wusste aber nicht wirklich, ob (und wie) ich in der Lage sein würde, diese Objekte zu verarbeiten.

//Result from MDN example, {value: quantity} 
{ 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 } 

So hatte ich die Idee, ein Objekt für jedes Keyword erstellen, mit einer Eigenschaft für seine Menge

{ 
    key: keyword, 
    count: n 
} 

und versucht, dies zu tun mit

let countKeywords = mapArrreduce((allKeywords, keyword) => { 
    if (allKeywords[0] != null && keyword in allKeywords[keyword]) { 
    allKeywords[keyword].count++ 
    } else { 
    allKeywords.push({ 
     keyword: keyword, 
     count: 1 
    }) 
    } 
    return allKeywords; 
}, []); 

aber mein Code doesn Ich arbeite nicht, und selbst nach zwei Tagen habe ich immer noch Mühe, es zum Laufen zu bringen, was mich dazu gebracht hat, diese Frage zu stellen (was für mich irgendwie neu ist, da ich meine Antworten immer auf Stackoverflow fand und deshalb nie musste Stellen Sie eine Frage selbst)

+0

Ihr letzter Schnipsel .... fehlt ein '.'? Ich würde erwarten, dass die {key: count} Struktur viel einfacher zu erstellen/zu arbeiten ist. Warum kannst du das MDN-Beispiel nicht verwenden? –

+0

Ihr erstes Objekt fehlt einige ',', und was ist der Name der Variablen? "cur"? Was ist "acc"? Würde auch helfen, wenn Sie mehr als eine Einheit von Array-Daten haben. – brandonscript

+0

'Um die einzelnen Werte zu verarbeiten, spalte ich das Array. Ist das nicht ein Fehler? Ihre Frage ist ziemlich unklar.Das MDN-Beispiel mit Ihrem Array flacht ordnungsgemäß funktioniert gut. –

Antwort

-1

Sollte in der Lage sein, es so zu tun. Da Sie eine Vielzahl verschachtelter Arrays verwenden, müssen Sie die Karte (+ concat) zweimal reduzieren. Sie können die Lesbarkeit vereinfachen, indem Sie diese in eine Prototyp-Methode konvertieren.

let flattenArr = [ 
    ["Comey, James B;Federal Bureau of Investigation;Trump, Donald J;United States Politics and Government"], 
    ["Trump, Donald J;Comey, James B;Federal Bureau of Investigation;United States Politics and Government"], 
    ["Trump, Donald J;Comey, James B;Federal Bureau of Investigation;United States Politics and Government"], 
    ["Trump, Donald J;Comey, James B;Federal Bureau of Investigation;United States Politics and Government"] 
] 

let mapArr = flattenArr.reduce((a, b) => a.concat(b)).map(words => words.split(";")).reduce((a, b) => a.concat(b)) 

let orderedCount = mapArr.reduce(function (acc, cur) { 
    if (typeof acc[cur] === 'undefined') { 
    acc[cur] = 1; 
    } else { 
    acc[cur] += 1; 
    } 

    return acc; 
}, {}) 

console.log(orderedCount) 

Ausgang:

{ 'Comey, James B': 4, 
    'Federal Bureau of Investigation': 4, 
    'Trump, Donald J': 4, 
    'United States Politics and Government': 4 } 

Hier ist der flatMap als Prototyp ext:

Array.prototype.flatMap = function(lambda) { 
    return Array.prototype.concat.apply([], this.map(lambda)); 
} 

dann verwenden:

let mapArr = flattenArr.flatMap(a => a).map(words => words.split(";")).flatMap(a => a) 
+0

Sorry für späte Antwort, ISP-Probleme ... Da ich ein JavaScript-Anfänger bin, was genau ist die "Verwendung" dieser/einer Prototyp-Methode? Natürlich habe ich über Prototyp-Methoden gelesen, aber bisher konnte ich den "Gebrauch" davon nicht verstehen. – Tobias

+0

Es ist im Grunde nur eine Erweiterung der Array-Klasse, mit der Sie Funktionen in Arrays ausführen und verketten können. – brandonscript

-1
let countKeywords = mapArr.reduce((allKeywords, keyword) => {//typo <== 
var elem=allKeywords.find(el=>el.keyword===keyword);//its an array so allKeywords[keyword] wont work... 
    if (elem) { 
     elem.count++ 
    } else { 
    allKeywords.push({ 
     keyword: keyword, 
     count: 1 
    }) 
} 
return allKeywords; 
}, []); 
Verwandte Themen