2016-05-12 3 views
2

Ich habe hier eine Reihe von Objekten.Underscore: Finden Sie das am häufigsten vorkommende Objekt in einem Array?

var list = [ 
    {"id": 439, "name": "John"}, 
    {"id": 439, "name": "John"}, 
    {"id": 100, "name": "Kevin"}, 
    {"id": 120, "name": "Max"}, 
    {"id": 439, "name": "John"} 
]; 

Ich muss aus diesem Array extrahieren, die am häufigsten vorkommende Objekt und bauen ein neues Array davon durch die beliebtesten Namen geordnet.

Bisher habe ich versucht, den Weg zu folgen aus diesem Thema Geographie: existiert Underscore.js: Find the most frequently occurring value in an array?

// Build temp list 
temp_list = _(
    _.chain(
     _(list).pluck('id') 
    ) 
    .countBy() 
    .pairs() 
    .value() 
) 
.sortBy(1) 
.reverse(); 

// Build final list with most frequently occurring first 
_.map(temp_list, function(current) { 
    return _.findWhere(list, { 
     'id': parseInt(current[0]) 
    }); 
}); 

könnte ein Weg, um diesen Code zu verbessern, indem sie ohne die Notwendigkeit, direkt erste Liste Sortierung eine temporäre Liste zu erstellen ?

+1

Alle Objekte in Ihrem Array sind unterschiedlich. Möchten Sie zwei Objekte als gleich betrachten, wenn ihre Eigenschaften 'id' und 'name' übereinstimmen? Nur "id"? – Oriol

Antwort

1

Sie haben es gerade verstanden: Sie könnten die Karte direkt vom reverse Anruf anrufen. Hier ist, wie ich es tat:

var newlist = _.chain(list) 
    .countBy(function (item) { return item.id; }) 
    .pairs() 
    .sortBy(function (item) { return item[1]; }) 
    .reverse() 
    .map(function (item) { return _.findWhere(list, { id: parseInt(item[0]) }); }) 
    .value(); 

Die Aufteilung:

Kette: gibt einen umhüllten Version des Arrays, das sind Sie Kette lassen Funktionen unterstreichen.

countBy: Gibt ein Objekt zurück, in dem die Schlüssel den Wert enthalten, der vom Rückruf zurückgegeben wird, und die Werte geben an, wie oft diese Schlüssel aufgetreten sind.

Paare: wandelt { key: 'value' } zu ['key', 'value']

sortBy: ein Array nach dem Wert sortiert kehrt aus dem Rückruf

Reverse zurückgegeben: umkehrt

Karte Array ausgeführt: gibt ein neues Array zurück, wobei jedes Element auf dem Element im ursprünglichen Array dieses Independant basiert x und was auch immer mit diesem Wert im Callback gemacht wird. In diesem Fall verwenden wir die id (item[0]), um das Objekt aus der ursprünglichen Liste zu erhalten.

Wert: entwirrt das kettenfähige Objekt und gibt den "rohen" Wert zurück.

0

können Sie reduce, verwenden Sie eine Anzahl der Elemente zu erhalten, danach ein sortBy

So etwas wie dieses

var list = [ 
 
    {"id": 439, "name": "John"}, 
 
    {"id": 439, "name": "John"}, 
 
    {"id": 100, "name": "Kevin"}, 
 
    {"id": 120, "name": "Max"}, 
 
    {"id": 439, "name": "John"} 
 
]; 
 

 
var finalList = _.chain(list) 
 
\t .reduce(function(memo, item){ 
 
\t var previous = _.findWhere(memo,{id:item.id}); 
 
    if(previous){ 
 
    \t previous.count++; 
 
    }else{ 
 
    \t item.count=1; 
 
    \t memo.push(item); 
 
    } 
 
    return memo; 
 
},[]) 
 
\t .sortBy('count') 
 
    .reverse() 
 
    .value();
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

1
_.chain(list) 
    .countBy("id").pairs().sortBy() 
    .reverse().map(function (element) {return _.findWhere(list, { id: parseInt(element[0]) }); }).value() 

var list = [ 
 
    {"id": 439, "name": "John"}, 
 
    {"id": 439, "name": "John"}, 
 
    {"id": 100, "name": "Kevin"}, 
 
    {"id": 120, "name": "Max"}, 
 
    {"id": 439, "name": "John"} 
 
]; 
 
var result = _.chain(list) 
 
    .countBy("id").pairs().sortBy() 
 
    .reverse().map(function (element) {return _.findWhere(list, { id: parseInt(element[0]) }); }).value(); 
 
console.log(result); 
 
document.write(JSON.stringify(result));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>