web-dev-qa-db-de.com

Sortiere das Array von Objekten nach einem einzigen Schlüssel mit Datumswert

Ich habe ein Array von Objekten mit mehreren Schlüsselwertpaaren, und ich muss sie basierend auf 'updated_at' sortieren:

[
    {
        "updated_at" : "2012-01-01T06:25:24Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-09T11:25:13Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-05T04:13:24Z",
        "foo" : "bar"
    }
]

Was ist der effizienteste Weg, dies zu tun?

192
user1022241

Sie können Array.sort verwenden.

Hier ist ein (ungeprüftes) Beispiel:

arr.sort(function(a, b){
    var keyA = new Date(a.updated_at),
        keyB = new Date(b.updated_at);
    // Compare the 2 dates
    if(keyA < keyB) return -1;
    if(keyA > keyB) return 1;
    return 0;
});
266
Rocket Hazmat

Ich habe hier schon eine wirklich ähnliche Frage beantwortet: Einfache Funktion zum Sortieren eines Arrays von Objekten

Für diese Frage habe ich diese kleine Funktion entwickelt, die vielleicht das tut, was Sie wollen:

function sortByKey(array, key) {
    return array.sort(function(a, b) {
        var x = a[key]; var y = b[key];
        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
}
142
David Brainer

Hier ist eine etwas modifizierte Version von @David Brainer-Bankers answer , die alphabetisch nach Zeichenfolge oder numerisch nach Zahl sortiert wird und gewährleistet, dass Wörter, die mit Großbuchstaben beginnen, nicht über Wörtern mit Kleinbuchstaben (z. Apple, Early "würde in dieser Reihenfolge angezeigt werden).

function sortByKey(array, key) {
    return array.sort(function(a, b) {
        var x = a[key];
        var y = b[key];

        if (typeof x == "string")
        {
            x = (""+x).toLowerCase(); 
        }
        if (typeof y == "string")
        {
            y = (""+y).toLowerCase();
        }

        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
}
17
Brad Parks

Die Array.sort () - Methode sortiert die Elemente eines Arrays an Ort und Stelle und gibt das Array zurück. Seien Sie vorsichtig mit Array.sort () , da es nicht Immutable ist. Verwenden Sie für unveränderliche Sortierung unveränderliche Sortierung .

Bei dieser Methode wird das Array mit Ihrem aktuellen updated_at im ISO-Format sortiert. Wir verwenden new Data(iso_string).getTime(), um die ISO-Zeit in Unix-Zeitstempel umzuwandeln. Ein Unix-Zeitstempel ist eine Zahl, mit der wir einfache Berechnungen ausführen können. Wir subtrahieren den ersten und zweiten Zeitstempel. Ist der erste Zeitstempel größer als der zweite, ist die Rückgabezahl positiv. Wenn die zweite Zahl größer als die erste ist, ist der Rückgabewert negativ. Wenn beide gleich sind, ist der Ertrag gleich Null. Dies stimmt perfekt mit den erforderlichen Rückgabewerten für die Inline-Funktion überein.

Für ES6 :

arr.sort((a,b) => new Date(a.updated_at).getTime() - new Date(b.updated_at).getTime());

Für ES5 :

arr.sort(function(a,b){ 
 return new Date(a.updated_at).getTime() - new Date(b.updated_at).getTime();
});

Wenn Sie Ihren updated_at in Unix-Zeitstempel ändern, können Sie Folgendes tun:

Für ES6 :

arr.sort((a,b) => a.updated_at - b.updated_at);

Für ES5 :

arr.sort(function(a,b){ 
 return a.updated_at - b.updated_at;
});

Zum Zeitpunkt dieses Beitrags unterstützen moderne Browser ES6 nicht. Um ES6 in modernen Browsern zu verwenden, verwenden Sie babel , um den Code auf ES5 zu verschieben. Erwarten Sie in naher Zukunft eine Browser-Unterstützung für ES6.

Array.sort () sollte einen Rückgabewert von 3 möglichen Ergebnissen erzielen:

  • Eine positive Zahl (erster Artikel> zweiter Artikel)
  • Eine negative Zahl (erster Artikel <zweiter Artikel)
  • 0, wenn die beiden Elemente gleich sind

Beachten Sie, dass der Rückgabewert für die Inline-Funktion beliebig sein kann positive oder negative Zahl. Array.Sort () kümmert sich nicht darum, was Rückkehrnummer ist. Es ist nur wichtig, wenn der Rückgabewert positiv ist, negativ oder null.

Für unveränderliche Sortierung: (Beispiel in ES6)

const sort = require('immutable-sort');
const array = [1, 5, 2, 4, 3];
const sortedArray = sort(array);

Sie können es auch so schreiben:

import sort from 'immutable-sort';
const array = [1, 5, 2, 4, 3];
const sortedArray = sort(array);

Der Import-from-Code ist ein neuer Weg, um Javascript in ES6 einzubinden und lässt Ihren Code sehr sauber aussehen. Mein persönlicher Favorit. 

Die unveränderliche Sortierung verändert das Quellarray nicht, sondern gibt ein neues Array zurück. Die Verwendung von const wird für unveränderliche Daten empfohlen.

17

Unterstriche js oder lodash verwenden,

var arrObj = [
    {
        "updated_at" : "2012-01-01T06:25:24Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-09T11:25:13Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-05T04:13:24Z",
        "foo" : "bar"
    }
];

arrObj = _.sortBy(arrObj,"updated_at");

_.sortBy() gibt ein neues Array zurück

refer http://underscorejs.org/#sortBy und lodash docs https://lodash.com/docs#sortBy

13
Mohammed Safeer

Als Status für This answer können Sie Array.sort verwenden.

arr.sort(function(a,b){return new Date(a.updated_at) - new Date(b.updated_at)})

arr = [
    {
        "updated_at" : "2012-01-01T06:25:24Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-09T11:25:13Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-05T04:13:24Z",
        "foo" : "bar"
    }
];
arr.sort(function(a,b){return new Date(a.updated_at) - new Date(b.updated_at)});
console.log(arr);
3
Ishpreet

Ich habe eine Sortierfunktion in TypeScript erstellt, mit der wir Zeichenfolgen, Datumsangaben und Zahlen in einer Reihe von Objekten suchen können. Es kann auch nach mehreren Feldern sortiert werden.

export type SortType = 'string' | 'number' | 'date';
export type SortingOrder = 'asc' | 'desc';

export interface SortOptions {
  sortByKey: string;
  sortType?: SortType;
  sortingOrder?: SortingOrder;
}


class CustomSorting {
    static sortArrayOfObjects(fields: SortOptions[] = [{sortByKey: 'value', sortType: 'string', sortingOrder: 'desc'}]) {
        return (a, b) => fields
          .map((field) => {
            if (!a[field.sortByKey] || !b[field.sortByKey]) {
              return 0;
            }

            const direction = field.sortingOrder === 'asc' ? 1 : -1;

            let firstValue;
            let secondValue;

            if (field.sortType === 'string') {
              firstValue = a[field.sortByKey].toUpperCase();
              secondValue = b[field.sortByKey].toUpperCase();
            } else if (field.sortType === 'number') {
              firstValue = parseInt(a[field.sortByKey], 10);
              secondValue = parseInt(b[field.sortByKey], 10);
            } else if (field.sortType === 'date') {
              firstValue = new Date(a[field.sortByKey]);
              secondValue = new Date(b[field.sortByKey]);
            }
            return firstValue > secondValue ? direction : firstValue < secondValue ? -(direction) : 0;

          })
          .reduce((pos, neg) => pos ? pos : neg, 0);
      }
    }
}

Verwendungszweck:

const sortOptions = [{
      sortByKey: 'anyKey',
      sortType: 'string',
      sortingOrder: 'asc',
    }];

arrayOfObjects.sort(CustomSorting.sortArrayOfObjects(sortOptions));
2
Ansuman

Nur eine weitere, mehrmathematische- Methode, um dasselbe zu tun, aber kürzer :

arr.sort(function(a, b){
    var diff = new Date(a.updated_at) - new Date(b.updated_at);
    return diff/(Math.abs(diff)||1);
});

oder im glatten Lambda-Pfeilstil:

arr.sort((a, b) => {
    var diff = new Date(a.updated_at) - new Date(b.updated_at);
    return diff/(Math.abs(diff)||1);
});

Diese Methode kann mit einer beliebigen numerischen Eingabe ausgeführt werden. 

2
Danny Mor

Mit ES2015-Unterstützung können Sie Folgendes tun:

foo.sort((a, b) => a.updated_at < b.updated_at ? -1 : 1)
1
knowbody

Das Sortieren nach einem ISO-formatierten Datum kann teuer sein, es sei denn, Sie beschränken sich auf die neuesten und besten Browser, die den korrekten Zeitstempel durch Datumsanalyse der Zeichenfolge erzeugen können.

Wenn Sie sicher Ihrer Eingabe sind und Sie wissen es wird immer yyyy-mm-ddThh: mm: ss und GMT (Z) sein, können Sie die Ziffern von jedem Element extrahieren und wie Ganzzahlen vergleichen

array.sort(function(a,b){
    return a.updated_at.replace(/\D+/g,'')-b.updated_at.replace(/\D+/g,'');
});

Wenn das Datum anders formatiert werden kann, müssen Sie möglicherweise etwas für iso-geforderte Leute hinzufügen:

Date.fromISO: function(s){
    var day, tz,
    rx=/^(\d{4}\-\d\d\-\d\d([tT ][\d:\.]*)?)([zZ]|([+\-])(\d\d):(\d\d))?$/,
    p= rx.exec(s) || [];
    if(p[1]){
        day= p[1].split(/\D/).map(function(itm){
            return parseInt(itm, 10) || 0;
        });
        day[1]-= 1;
        day= new Date(Date.UTC.apply(Date, day));
        if(!day.getDate()) return NaN;
        if(p[5]){
            tz= (parseInt(p[5], 10)*60);
            if(p[6]) tz+= parseInt(p[6], 10);
            if(p[4]== '+') tz*= -1;
            if(tz) day.setUTCMinutes(day.getUTCMinutes()+ tz);
        }
        return day;
    }
    return NaN;
}
if(!Array.prototype.map){
    Array.prototype.map= function(fun, scope){
        var T= this, L= T.length, A= Array(L), i= 0;
        if(typeof fun== 'function'){
            while(i< L){
                if(i in T){
                    A[i]= fun.call(scope, T[i], i, T);
                }
                ++i;
            }
            return A;
        }
    }
}
}
1
kennebec

Importierte Daten

[
    {
        "gameStatus": "1",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-20 11:32:04"
    },
    {
        "gameStatus": "0",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 18:08:24"
    },
    {
        "gameStatus": "2",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 18:35:40"
    },
    {
        "gameStatus": "0",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 10:42:53"
    },
    {
        "gameStatus": "2",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-20 10:54:09"
    },
    {
        "gameStatus": "0",
        "userId": "1a2fefb0-5ae2-47eb-82ff-d1b2cc27875a",
        "created_at": "2018-12-19 18:46:22"
    },
    {
        "gameStatus": "1",
        "userId": "7118ed61-d8d9-4098-a81b-484158806d21",
        "created_at": "2018-12-20 10:50:48"
    }
]

für aufsteigende Reihenfolge

arr.sort(function(a, b){
    var keyA = new Date(a.updated_at),
        keyB = new Date(b.updated_at);
    // Compare the 2 dates
    if(keyA < keyB) return -1;
    if(keyA > keyB) return 1;
    return 0;
});

Beispiel für eine Asc-Bestellung

[
    {
        "gameStatus": "0",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 10:42:53"
    },
    {
        "gameStatus": "0",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 18:08:24"
    },
    {
        "gameStatus": "2",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 18:35:40"
    },
    {
        "gameStatus": "0",
        "userId": "1a2fefb0-5ae2-47eb-82ff-d1b2cc27875a",
        "created_at": "2018-12-19 18:46:22"
    },
    {
        "gameStatus": "1",
        "userId": "7118ed61-d8d9-4098-a81b-484158806d21",
        "created_at": "2018-12-20 10:50:48"
    },
    {
        "gameStatus": "2",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-20 10:54:09"
    },
    {
        "gameStatus": "1",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-20 11:32:04"
    }
]

FÜR absteigende Reihenfolge

arr.sort(function(a, b){
    var keyA = new Date(a.updated_at),
        keyB = new Date(b.updated_at);
    // Compare the 2 dates
    if(keyA > keyB) return -1;
    if(keyA < keyB) return 1;
    return 0;
});

Beispiel für Desc-Auftrag

[
    {
        "gameStatus": "1",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-20 11:32:04"
    },
    {
        "gameStatus": "2",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-20 10:54:09"
    },
    {
        "gameStatus": "1",
        "userId": "7118ed61-d8d9-4098-a81b-484158806d21",
        "created_at": "2018-12-20 10:50:48"
    },
    {
        "gameStatus": "0",
        "userId": "1a2fefb0-5ae2-47eb-82ff-d1b2cc27875a",
        "created_at": "2018-12-19 18:46:22"
    },
    {
        "gameStatus": "2",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 18:35:40"
    },
    {
        "gameStatus": "0",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 18:08:24"
    },
    {
        "gameStatus": "0",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 10:42:53"
    }
]
1
Anandan K

Antworten auf @knowbody ( https://stackoverflow.com/a/42418963/6778546 ) und @Rocket Hazmat ( https://stackoverflow.com/a/8837511/6778546 ) kann kombiniert werden, um die Unterstützung für ES2015 und die korrekte Datumsbehandlung zu gewährleisten:

arr.sort((a, b) => {
   const dateA = new Date(a.updated_at);
   const dateB = new Date(b.updated_at);
   return dateA - dateB;
});
1
Fyodor

Der Vollständigkeit halber sei hier eine mögliche kurze generische Implementierung von sortBy aufgeführt:

function sortBy(list, keyFunc) {
  return list.sort((a,b) => keyFunc(a) - keyFunc(b));
}

sortBy([{"key": 2}, {"key": 1}], o => o["key"])

Beachten Sie, dass hierbei die Arrays-Sortiermethode verwendet wird, die an Ort und Stelle sortiert wird. Für eine Kopie können Sie arr.concat () oder arr.slice (0) oder eine ähnliche Methode zum Erstellen einer Kopie verwenden.

0
Legion
  • Verwenden Sie Array.sort() , um ein Array zu sortieren
  • Klonen Sie das Array mit Spread-Operator (), um die Funktion rein zu machen
  • Nach gewünschter Taste sortieren (updated_at)
  • Konvertiere Datumsstring nach Datumsobjekt
  • Array.sort() subtrahiert zwei Eigenschaften vom aktuellen und nächsten Element, wenn es sich um eine Zahl/ein Objekt handelt, an dem Sie arrhythmische Operationen ausführen können
const input = [
  {
    updated_at: '2012-01-01T06:25:24Z',
    foo: 'bar',
  },
  {
    updated_at: '2012-01-09T11:25:13Z',
    foo: 'bar',
  },
  {
    updated_at: '2012-01-05T04:13:24Z',
    foo: 'bar',
  }
];

const sortByUpdatedAt = (items) => [...items].sort((itemA, itemB) => new Date(itemA.updated_at) - new Date(itemB.updated_at));

const output = sortByUpdatedAt(input);

console.log(input);
/*
[ { updated_at: '2012-01-01T06:25:24Z', foo: 'bar' }, 
  { updated_at: '2012-01-09T11:25:13Z', foo: 'bar' }, 
  { updated_at: '2012-01-05T04:13:24Z', foo: 'bar' } ]
*/
console.log(output)
/*
[ { updated_at: '2012-01-01T06:25:24Z', foo: 'bar' }, 
  { updated_at: '2012-01-05T04:13:24Z', foo: 'bar' }, 
  { updated_at: '2012-01-09T11:25:13Z', foo: 'bar' } ]
*/
0
marcobiedermann
var months = [
    {
        "updated_at" : "2012-01-01T06:25:24Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-09T11:25:13Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-05T04:13:24Z",
        "foo" : "bar"
    }];
months.sort((a, b)=>{
    var keyA = new Date(a.updated_at),
        keyB = new Date(b.updated_at);
    // Compare the 2 dates
    if(keyA < keyB) return -1;
    if(keyA > keyB) return 1;
    return 0;
});
console.log(months);
0
Prasad

Damit können wir eine Schlüsselfunktion zur Sortierung übergeben

Array.prototype.sortBy = function(key_func, reverse=false){
    return this.sort( (a, b) => {
        var keyA = key_func(a),
            keyB = key_func(b);
        if(keyA < keyB) return reverse? 1: -1;
        if(keyA > keyB) return reverse? -1: 1;
        return 0;
    }); 
}

Dann zum Beispiel, wenn wir haben

var arr = [ {date: "01/12/00", balls: {red: "a8",  blue: 10}},
            {date: "12/13/05", balls: {red: "d6" , blue: 11}},
            {date: "03/02/04", balls: {red: "c4" , blue: 15}} ]

Wir können tun

arr.sortBy(el => el.balls.red)
/* would result in
[ {date: "01/12/00", balls: {red: "a8", blue: 10}},
  {date: "03/02/04", balls: {red: "c4", blue: 15}},
  {date: "12/13/05", balls: {red: "d6", blue: 11}} ]
*/

oder 

arr.sortBy(el => new Date(el.date), true)   // second argument to reverse it
/* would result in
[ {date: "12/13/05", balls: {red: "d6", blue:11}},
  {date: "03/02/04", balls: {red: "c4", blue:15}},
  {date: "01/12/00", balls: {red: "a8", blue:10}} ]
*/

oder

arr.sortBy(el => el.balls.blue + parseInt(el.balls.red[1]))
/* would result in
[ {date: "12/13/05", balls: {red: "d6", blue:11}},    // red + blue= 17
  {date: "01/12/00", balls: {red: "a8", blue:10}},    // red + blue= 18
  {date: "03/02/04", balls: {red: "c4", blue:15}} ]   // red + blue= 19
*/
0
aljgom

Sie können einen Abschluss erstellen und so weitergeben Hier ist mein Beispiel, das arbeitet.

$.get('https://data.seattle.gov/resource/3k2p-39jp.json?$limit=10&$where=within_circle(incident_location, 47.594972, -122.331518, 1609.34)', 
  function(responce) {

    var filter = 'event_clearance_group', //sort by key group name
    data = responce; 

    var compare = function (filter) {
        return function (a,b) {
            var a = a[filter],
                b = b[filter];

            if (a < b) {
                return -1;
            } else if (a > b) {
                return 1;
            } else {
                return 0;
            }
        };
    };

    filter = compare(filter); //set filter

    console.log(data.sort(filter));
});
0
Michael Guild