2011-01-02 15 views
32

W jaki sposób posortować dane według wartości count i year w porządku rosnącym w kolejności rosnącej z wartością count?Posortuj według dwóch wartości, ustalając priorytety na jednym z nich.

//sort this 
var data = [ 
    { count: '12', year: '1956' }, 
    { count: '1', year: '1971' }, 
    { count: '33', year: '1989' }, 
    { count: '33', year: '1988' } 
]; 
//to get this 
var data = [ 
    { count: '1', year: '1971' }, 
    { count: '12', year: '1956' }, 
    { count: '33', year: '1988' }, 
    { count: '33', year: '1989' }, 
]; 

Odpowiedz

41

(See the jsfiddle)

data.sort(function (x, y) { 
    var n = x.count - y.count; 
    if (n !== 0) { 
     return n; 
    } 

    return x.year - y.year; 
}); 
+15

One-liner 'data.sort (funkcja (x, y) {return x.count - y.count || x.year - y.year;});' –

+0

@LucaSteeb Twoje rozwiązanie działało jak mistrz i uratowałem mój dzień. –

+1

@cdhowie masz rację, naprawdę muszę w pełni zrozumieć, jak działają algorytmy sortowania. Usuwam moje komentarze, dziękuję. –

12

można wykorzystywać metodę JavaScript w .sort() array (try it out):

data.sort(function(a, b) { 
    // Sort by count 
    var dCount = a.count - b.count; 
    if(dCount) return dCount; 

    // If there is a tie, sort by year 
    var dYear = a.year - b.year; 
    return dYear; 
}); 

Uwaga: zmienia oryginalnej tablicy. Jeśli trzeba wykonać kopię pierwsze, można to zrobić:

var dataCopy = data.slice(0); 
+0

sprawdź mój jednolinijkowy na pytanie powyżej –

5

trzeba wypracować ten problem jak ten sposób

var customSort = function(name, type){ 
    return function(o, p){ 
     var a, b; 
     if(o && p && typeof o === 'object' && typeof p === 'object'){ 
      a = o[name]; 
      b = p[name]; 
      if(a === b){ 
       return typeof type === 'function' ? type(o, p) : o; 
      } 

      if(typeof a=== typeof b){ 
       return a < b ? -1 : 1; 
      } 
      return typeof a < typeof b ? -1 : 1; 
     } 
    }; 

};

np .: data.sort (customSort ('rok', customSort ('count'))));

+0

, że funkcja pomaga mi tak dużo: D –

+0

po wszystkim sh! T; to w końcu działa: D thnx. – mayankcpdixit

+0

opcjonalne odwrotne byłoby niesamowite mieć tutaj. – mayankcpdixit

27

Prostym rozwiązaniem jest:

data.sort(function (a, b) { 
    return a.count - b.count || a.year - b.year; 
}); 

To działa, ponieważ jeśli Ilość jest inny, wówczas rodzaj opiera się na tym. Jeśli zlicza jest takie samo, pierwsze wyrażenie zwraca 0, które przekształca się w , fałszywe, a wynik drugiego wyrażenia jest używany (tj. Sortowanie jest oparte na roku).

+1

Ładne użycie 0 jako falsey! –

+0

Wersja ES: data.sort ((a, b) => (a.count - b.count || a.year - b.year)); –

1

użytkownik tego gdzie „count” -> priorytetem i „lata” -> Drugi priorytet

data.sort(function(a,b){ 
    return a['count']<b['count']?-1:(a['count']>b['count']?1:(a['year']<b['year']?-1:1)); 
}); 
3

Bazując na wielką @RobG simple solution, I utworzeniu funkcji sortowania według wielu różnych właściwościach, przy użyciu JS2015 trudne na map + find:

let sortBy = (p, a) => a.sort((i, j) => p.map(v => i[v] - j[v]).find(r => r)) 

sortBy(['count', 'year'], data) 

Ponadto, jeśli wolisz, tradycyjna wersja JS (stosować z ostrożnością ze względu na find compatibility w starych przeglądarek):

var sortBy = function (properties, targetArray) { 
    targetArray.sort(function (i, j) { 
    return properties.map(function (prop) { 
     return i[prop] - j[prop]; 
    }).find(function (result) { 
     return result; 
    }); 
    }); 
}; 
1

Jeśli szukasz sortowania ciągów znaków w kolejności alfabetycznej, a nie liczb, oto przykładowy problem i jego rozwiązanie.

Przykład problemu: tablicy tablic (finalArray) z pierwszym wejściem a ścieżka katalogu i trzecim nazwa pliku; sortuj tak, aby tablica była układana najpierw według folderu, a wewnątrz identycznych folderów, według nazwy pliku.

E.g.po sortowaniu można oczekiwać:

[['folder1', 'abc.jpg'], 
['folder1', 'xyz.jpg'], 
['folder2', 'def.jpg'], 
['folder2', 'pqr.jpg']] 

Patrz Array.prototype.sort() - compareFunction

finalArray.sort((x: any, y: any): number => { 
    const folder1: string = x[0].toLowerCase(); 
    const folder2: string = y[0].toLowerCase(); 
    const file1: string = x[1].toLowerCase(); 
    const file2: string = y[1].toLowerCase(); 

    if (folder1 > folder2) { 
    return 1; 
    } else if (folder1 === folder2 && file1 > file2) { 
    return 1; 
    } else if (folder1 === folder2 && file1 === file2) { 
    return 0; 
    } else if (folder1 === folder2 && file1 < file2) { 
    return -1; 
    } else if (folder1 < folder2) { 
    return -1; 
    } 
}); 

Pamiętaj, "Z" jest przed "A" (stolic najpierw według punkt kodowy Unicode), dlatego mam toLowerCase(). Problem, którego powyższa implementacja nie rozwiązuje, to "10abc" pojawi się przed "9abc".

Powiązane problemy