Ordenar una matriz de objetos por valores de propiedad

1334

Tengo los siguientes objetos usando AJAX y los almacené en una matriz:

var homes = [
    {
        "h_id": "3",
        "city": "Dallas",
        "state": "TX",
        "zip": "75201",
        "price": "162500"
    }, {
        "h_id": "4",
        "city": "Bevery Hills",
        "state": "CA",
        "zip": "90210",
        "price": "319250"
    }, {
        "h_id": "5",
        "city": "New York",
        "state": "NY",
        "zip": "00010",
        "price": "962500"
    }
];

¿Cómo creo una función para ordenar los objetos por la pricepropiedad en orden ascendente o descendente usando solo JavaScript?

TomHankers
fuente
la forma más rápida es utilizar el módulo de ordenamiento isomorfo que funciona de forma nativa tanto en el navegador como en el nodo, que admite cualquier tipo de entrada, campos calculados y órdenes de clasificación personalizadas.
Lloyd

Respuestas:

1674

Ordenar casas por precio en orden ascendente:

homes.sort(function(a, b) {
    return parseFloat(a.price) - parseFloat(b.price);
});

O después de la versión ES6:

homes.sort((a, b) => parseFloat(a.price) - parseFloat(b.price));

Alguna documentación se puede encontrar aquí .

Stobor
fuente
184
Puede usar string1.localeCompare(string2)para la comparación de cadenas
bradvido
62
Tenga en cuenta que no distingue entrelocaleCompare() mayúsculas y minúsculas . Si desea mayúsculas y minúsculas, puede usar (string1 > string2) - (string1 < string2). Los valores booleanos se convierten en enteros 0 y 1 para calcular la diferencia.
Don Kirkby
2
Gracias por la actualización, @Pointy, no recuerdo haber encontrado este problema, pero quizás el comportamiento ha cambiado en los últimos años. En cualquier caso, la localeCompare()documentación muestra que puede indicar explícitamente si desea mayúsculas y minúsculas, clasificación numérica y otras opciones.
Don Kirkby
2
@ sg28 Creo que ha entendido mal la explicación de MDN. No dice que la función de clasificación no es confiable , dice que no es estable . Entiendo por qué esto puede ser confuso, pero eso no es una afirmación de que no es adecuado para su uso. En el contexto de los algoritmos de clasificación, el término estable tiene un significado específico: que los elementos "iguales" en la lista se ordenan en el mismo orden que en la entrada . Esto no tiene ninguna relación con la idea de código que es inestable (es decir, aún no está listo para usar).
Stobor
1
Si desea ordenar por una cadena de valores específicos, por ejemplo, por ciudad, puede usar: this.homes.sort ((current, next) => {return current.city.localeCompare (next.city)});
Jorge Valvert
675

Aquí hay una versión más flexible, que le permite crear funciones de ordenación reutilizables y ordenar por cualquier campo.

const sort_by = (field, reverse, primer) => {

  const key = primer ?
    function(x) {
      return primer(x[field])
    } :
    function(x) {
      return x[field]
    };

  reverse = !reverse ? 1 : -1;

  return function(a, b) {
    return a = key(a), b = key(b), reverse * ((a > b) - (b > a));
  }
}


//Now you can sort by any field at will...

const homes=[{h_id:"3",city:"Dallas",state:"TX",zip:"75201",price:"162500"},{h_id:"4",city:"Bevery Hills",state:"CA",zip:"90210",price:"319250"},{h_id:"5",city:"New York",state:"NY",zip:"00010",price:"962500"}];

// Sort by price high to low
console.log(homes.sort(sort_by('price', true, parseInt)));

// Sort by city, case-insensitive, A-Z
console.log(homes.sort(sort_by('city', false, (a) =>  a.toUpperCase()
)));

Tríptico
fuente
77
nickb: estás leyendo mal el código. sort_byse ejecuta en O (1) y devuelve una función utilizada por la ordenación integrada (O (N log N)) para comparar elementos en una lista. La complejidad total es O (n log n) * O (1) que se reduce a O (n log n), o lo mismo que una ordenación rápida.
Tríptico
1
Un problema que tengo con esto es que con reverse = false, ordenará los números como 1,2,3,4 ... pero las cadenas como z, y, x ...
Abby
44
Una pequeña mejora:var key = primer ? function (x) { return primer(x[field]); } : function (x) { return x[field]; }
ErikE
66
Si bien se [1,-1][+!!reverse]ve genial, es algo horrible de hacer. Si un usuario no puede llamar a su método correctamente, castíguelo, no intente darle sentido, pase lo que pase.
Ingo Bürk
2
No sería mejor preparar los datos de origen, esto causaría un análisis consecutivo cuando claramente los datos de origen necesiten algunos ajustes.
Gerrit Brink
134

Para ordenarlo, debe crear una función de comparación que tome dos argumentos. Luego llame a la función de clasificación con esa función de comparación de la siguiente manera:

// a and b are object elements of your array
function mycomparator(a,b) {
  return parseInt(a.price, 10) - parseInt(b.price, 10);
}
homes.sort(mycomparator);

Si desea ordenar de forma ascendente, cambie las expresiones a cada lado del signo menos.

Ricardo Marimon
fuente
3
Y aquí hay una referencia que realmente explica el tema en lugar de decir "es demasiado complicado, no lo entenderás de todos modos": developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Roland Illig
51

para ordenar cadenas en caso de que alguien lo necesite,

const dataArr = {

  "hello": [{
    "id": 114,
    "keyword": "zzzzzz",
    "region": "Sri Lanka",
    "supportGroup": "administrators",
    "category": "Category2"
  }, {
    "id": 115,
    "keyword": "aaaaa",
    "region": "Japan",
    "supportGroup": "developers",
    "category": "Category2"
  }]

};
const sortArray = dataArr['hello'];

console.log(sortArray.sort((a, b) => {
  if (a.region < b.region)
    return -1;
  if (a.region > b.region)
    return 1;
  return 0;
}));

Ishan Liyanage
fuente
38

Si tiene un navegador compatible con ES6 , puede usar:

La diferencia entre el orden de clasificación ascendente y descendente es el signo del valor devuelto por su función de comparación:

var ascending = homes.sort((a, b) => Number(a.price) - Number(b.price));
var descending = homes.sort((a, b) => Number(b.price) - Number(a.price));

Aquí hay un fragmento de código que funciona:

var homes = [{
  "h_id": "3",
  "city": "Dallas",
  "state": "TX",
  "zip": "75201",
  "price": "162500"
}, {
  "h_id": "4",
  "city": "Bevery Hills",
  "state": "CA",
  "zip": "90210",
  "price": "319250"
}, {
  "h_id": "5",
  "city": "New York",
  "state": "NY",
  "zip": "00010",
  "price": "962500"
}];

homes.sort((a, b) => Number(a.price) - Number(b.price));
console.log("ascending", homes);

homes.sort((a, b) => Number(b.price) - Number(a.price));
console.log("descending", homes);

Stephen Quan
fuente
22

¿Quieres ordenarlo en Javascript, verdad? Lo que quieres es la sort()función . En este caso, debe escribir una función de comparación y pasarla sort(), así que algo como esto:

function comparator(a, b) {
    return parseInt(a["price"], 10) - parseInt(b["price"], 10);
}

var json = { "homes": [ /* your previous data */ ] };
console.log(json["homes"].sort(comparator));

Su comparador toma uno de cada uno de los hashes anidados dentro de la matriz y decide cuál es más alto marcando el campo "precio".

Tim Gilbert
fuente
21

Recomiendo GitHub: Array sortBy : una mejor implementación del sortBymétodo que utiliza la transformación Schwartzian

Pero por ahora vamos a probar este enfoque Gist: sortBy-old.js .
Creemos un método para ordenar las matrices pudiendo organizar los objetos por alguna propiedad.

Crear la función de clasificación

var sortBy = (function () {
  var toString = Object.prototype.toString,
      // default parser function
      parse = function (x) { return x; },
      // gets the item to be sorted
      getItem = function (x) {
        var isObject = x != null && typeof x === "object";
        var isProp = isObject && this.prop in x;
        return this.parser(isProp ? x[this.prop] : x);
      };

  /**
   * Sorts an array of elements.
   *
   * @param  {Array} array: the collection to sort
   * @param  {Object} cfg: the configuration options
   * @property {String}   cfg.prop: property name (if it is an Array of objects)
   * @property {Boolean}  cfg.desc: determines whether the sort is descending
   * @property {Function} cfg.parser: function to parse the items to expected type
   * @return {Array}
   */
  return function sortby (array, cfg) {
    if (!(array instanceof Array && array.length)) return [];
    if (toString.call(cfg) !== "[object Object]") cfg = {};
    if (typeof cfg.parser !== "function") cfg.parser = parse;
    cfg.desc = !!cfg.desc ? -1 : 1;
    return array.sort(function (a, b) {
      a = getItem.call(cfg, a);
      b = getItem.call(cfg, b);
      return cfg.desc * (a < b ? -1 : +(a > b));
    });
  };

}());

Establecer datos sin clasificar

var data = [
  {date: "2011-11-14T16:30:43Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T17:22:59Z", quantity: 2, total: 90,  tip: 0,   type: "Tab"},
  {date: "2011-11-14T16:28:54Z", quantity: 1, total: 300, tip: 200, type: "visa"},
  {date: "2011-11-14T16:53:41Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:48:46Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T17:25:45Z", quantity: 2, total: 200, tip: 0,   type: "cash"},
  {date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"},
  {date: "2011-11-14T16:58:03Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T17:07:21Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0,   type: "Cash"}
];

Usándolo

Organizar la matriz, "date"comoString

// sort by @date (ascending)
sortBy(data, { prop: "date" });

// expected: first element
// { date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" }

// expected: last element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"}

Si desea ignorar mayúsculas y minúsculas, configure la parserdevolución de llamada:

// sort by @type (ascending) IGNORING case-sensitive
sortBy(data, {
    prop: "type",
    parser: (t) => t.toUpperCase()
});

// expected: first element
// { date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "Cash" }

// expected: last element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa" }

Si desea convertir el "date"campo como Datetipo:

// sort by @date (descending) AS Date object
sortBy(data, {
    prop: "date",
    desc: true,
    parser: (d) => new Date(d)
});

// expected: first element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"}

// expected: last element
// { date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" }

Aquí puedes jugar con el código: jsbin.com/lesebi

Gracias a @Ozesh por sus comentarios, se solucionó el problema relacionado con las propiedades con valores falsos .

jherax
fuente
Esto parece romperse cuando un campo es nulo.
TSNev
En caso de que esté ordenando números y encuentre un '0' entre la matriz de objetos, puede notar que el código anterior se rompe. Aquí hay una solución rápida para eso: var checkNaN = function (value) { return Number.isNaN(Number(value)) ? 0 : value; } seguido de: función de retorno (matriz, o) { .... a = _getItem.call (o, a); a = checkNaN (a); b = _getItem.call (o, b); b = checkNaN (b); return o.desc * (a <b? -1: + (a> b)); });
Ozesh
18

Use lodash.sortBy , (instrucciones usando commonjs, también puede poner el script include-tag para el cdn en la parte superior de su html)

var sortBy = require('lodash.sortby');
// or
sortBy = require('lodash').sortBy;

Orden descendiente

var descendingOrder = sortBy( homes, 'price' ).reverse();

Orden ascendente

var ascendingOrder = sortBy( homes, 'price' );
Evan Carroll
fuente
1
Oconst sortBy = require('lodash/sortBy'); let calendars = sortBy(calendarListResponse.items, cal => cal.summary);
mpen
no estoy seguro si loadash cambiado recientemente por ahora su nombre OrdenarPorimport { orderBy } from 'lodash'; ... ... return orderBy ( rows, 'fieldName' ).reverse();
montelof
8

Esto podría haberse logrado a través de una función de clasificación simple de una línea valueof () . Ejecute el fragmento de código a continuación para ver la demostración.

var homes = [
    {
        "h_id": "3",
        "city": "Dallas",
        "state": "TX",
        "zip": "75201",
        "price": "162500"
    }, {
        "h_id": "4",
        "city": "Bevery Hills",
        "state": "CA",
        "zip": "90210",
        "price": "319250"
    }, {
        "h_id": "5",
        "city": "New York",
        "state": "NY",
        "zip": "00010",
        "price": "962500"
    }
];

console.log("To sort descending/highest first, use operator '<'");

homes.sort(function(a,b) { return a.price.valueOf() < b.price.valueOf();});

console.log(homes);

console.log("To sort ascending/lowest first, use operator '>'");

homes.sort(function(a,b) { return a.price.valueOf() > b.price.valueOf();});

console.log(homes);

Ajay Singh
fuente
8

Llego un poco tarde a la fiesta, pero a continuación está mi lógica para ordenar.

function getSortedData(data, prop, isAsc) {
    return data.sort((a, b) => {
        return (a[prop] < b[prop] ? -1 : 1) * (isAsc ? 1 : -1)
    });
}
Santosh
fuente
6

Si bien soy consciente de que el OP quería ordenar una serie de números, esta pregunta se ha marcado como la respuesta para preguntas similares con respecto a las cadenas. A ese hecho, las respuestas anteriores no consideran ordenar una matriz de texto donde la carcasa es importante. La mayoría de las respuestas toman los valores de cadena y los convierten a mayúsculas / minúsculas y luego los ordenan de una forma u otra. Los requisitos a los que me adhiero son simples:

  • Ordenar alfabéticamente AZ
  • Los valores en mayúscula de la misma palabra deben aparecer antes que los valores en minúscula
  • Los mismos valores de letras (A / a, B / b) deben agruparse

Lo que espero es [ A, a, B, b, C, c ]pero las respuestas anteriores regresan A, B, C, a, b, c. De hecho, me rasqué la cabeza por más tiempo de lo que quería (por eso publico esto con la esperanza de que ayude al menos a otra persona). Si bien dos usuarios mencionan la localeComparefunción en los comentarios para la respuesta marcada, no lo vi hasta después de tropezar con la función mientras buscaba. Después de leer la documentación de String.prototype.localeCompare () pude llegar a esto:

var values = [ "Delta", "charlie", "delta", "Charlie", "Bravo", "alpha", "Alpha", "bravo" ];
var sorted = values.sort((a, b) => a.localeCompare(b, undefined, { caseFirst: "upper" }));
// Result: [ "Alpha", "alpha", "Bravo", "bravo", "Charlie", "charlie", "Delta", "delta" ]

Esto le dice a la función que ordene los valores en mayúscula antes que los valores en minúscula. El segundo parámetro en la localeComparefunción es definir el entorno local, pero si lo deja, ya undefinedque automáticamente determina el entorno local por usted.

Esto funciona igual para ordenar una matriz de objetos también:

var values = [
    { id: 6, title: "Delta" },
    { id: 2, title: "charlie" },
    { id: 3, title: "delta" },
    { id: 1, title: "Charlie" },
    { id: 8, title: "Bravo" },
    { id: 5, title: "alpha" },
    { id: 4, title: "Alpha" },
    { id: 7, title: "bravo" }
];
var sorted = values
    .sort((a, b) => a.title.localeCompare(b.title, undefined, { caseFirst: "upper" }));
Mitchell Skurnik
fuente
5

Puede usar el sortmétodo JavaScript con una función de devolución de llamada:

function compareASC(homeA, homeB)
{
    return parseFloat(homeA.price) - parseFloat(homeB.price);
}

function compareDESC(homeA, homeB)
{
    return parseFloat(homeB.price) - parseFloat(homeA.price);
}

// Sort ASC
homes.sort(compareASC);

// Sort DESC
homes.sort(compareDESC);
John G
fuente
4

Aquí hay una culminación de todas las respuestas anteriores.

Validación de violín: http://jsfiddle.net/bobberino/4qqk3/

var sortOn = function (arr, prop, reverse, numeric) {

    // Ensure there's a property
    if (!prop || !arr) {
        return arr
    }

    // Set up sort function
    var sort_by = function (field, rev, primer) {

        // Return the required a,b function
        return function (a, b) {

            // Reset a, b to the field
            a = primer(a[field]), b = primer(b[field]);

            // Do actual sorting, reverse as needed
            return ((a < b) ? -1 : ((a > b) ? 1 : 0)) * (rev ? -1 : 1);
        }

    }

    // Distinguish between numeric and string to prevent 100's from coming before smaller
    // e.g.
    // 1
    // 20
    // 3
    // 4000
    // 50

    if (numeric) {

        // Do sort "in place" with sort_by function
        arr.sort(sort_by(prop, reverse, function (a) {

            // - Force value to a string.
            // - Replace any non numeric characters.
            // - Parse as float to allow 0.02 values.
            return parseFloat(String(a).replace(/[^0-9.-]+/g, ''));

        }));
    } else {

        // Do sort "in place" with sort_by function
        arr.sort(sort_by(prop, reverse, function (a) {

            // - Force value to string.
            return String(a).toUpperCase();

        }));
    }


}
Beto
fuente
¿puede explicar cuál es el significado de tener * (rev? -1: 1);
TechTurtle
Eso es para revertir el orden (ascendente vs descendente), la porción de revoluciones simplemente da vuelta a los resultados normales cuando el argumento rev es verdadero. De lo contrario, solo se multiplicará por 1, lo que no hace nada; cuando se establece, multiplicará el resultado por -1, invirtiendo así el resultado.
bob
3

Para ordenar una matriz, debe definir una función de comparación. Esta función siempre será diferente en su patrón u orden de clasificación deseado (es decir, ascendente o descendente).

Dejemos crear algunas funciones que ordenen una matriz ascendente o descendente y que contenga objetos o cadenas o valores numéricos.

function sorterAscending(a,b) {
    return a-b;
}

function sorterDescending(a,b) {
    return b-a;
}

function sorterPriceAsc(a,b) {
    return parseInt(a['price']) - parseInt(b['price']);
}

function sorterPriceDes(a,b) {
    return parseInt(b['price']) - parseInt(b['price']);
}

Ordenar números (alfabéticamente y ascendentes):

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();

Ordenar números (alfabéticamente y descendentes):

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();
fruits.reverse();

Ordenar números (numéricos y ascendentes):

var points = [40,100,1,5,25,10];
points.sort(sorterAscending());

Ordenar números (numéricamente y descendentes):

var points = [40,100,1,5,25,10];
points.sort(sorterDescending());

Como arriba, use el método sorterPriceAsc y sorterPriceDes con su matriz con la clave deseada.

homes.sort(sorterPriceAsc()) or homes.sort(sorterPriceDes())
Lalit Kumar Maurya
fuente
3

También trabajé con algún tipo de clasificación y varios campos:

arr = [
    {type:'C', note:834},
    {type:'D', note:732},
    {type:'D', note:008},
    {type:'F', note:474},
    {type:'P', note:283},
    {type:'P', note:165},
    {type:'X', note:173},
    {type:'Z', note:239},
];

arr.sort(function(a,b){        
    var _a = ((a.type==='C')?'0':(a.type==='P')?'1':'2');
    _a += (a.type.localeCompare(b.type)===-1)?'0':'1';
    _a += (a.note>b.note)?'1':'0';
    var _b = ((b.type==='C')?'0':(b.type==='P')?'1':'2');
    _b += (b.type.localeCompare(a.type)===-1)?'0':'1';
    _b += (b.note>a.note)?'1':'0';
    return parseInt(_a) - parseInt(_b);
});

Resultado

[
    {"type":"C","note":834},
    {"type":"P","note":165},
    {"type":"P","note":283},
    {"type":"D","note":8},
    {"type":"D","note":732},
    {"type":"F","note":474},
    {"type":"X","note":173},
    {"type":"Z","note":239}
]
Rodolfo Jorge Nemer Nogueira
fuente
3

Si bien es un poco exagerado simplemente ordenar una sola matriz, esta función prototipo permite ordenar las matrices Javascript por cualquier clave, en orden ascendente o descendente, incluidas las claves anidadas , utilizando la dotsintaxis.

(function(){
    var keyPaths = [];

    var saveKeyPath = function(path) {
        keyPaths.push({
            sign: (path[0] === '+' || path[0] === '-')? parseInt(path.shift()+1) : 1,
            path: path
        });
    };

    var valueOf = function(object, path) {
        var ptr = object;
        for (var i=0,l=path.length; i<l; i++) ptr = ptr[path[i]];
        return ptr;
    };

    var comparer = function(a, b) {
        for (var i = 0, l = keyPaths.length; i < l; i++) {
            aVal = valueOf(a, keyPaths[i].path);
            bVal = valueOf(b, keyPaths[i].path);
            if (aVal > bVal) return keyPaths[i].sign;
            if (aVal < bVal) return -keyPaths[i].sign;
        }
        return 0;
    };

    Array.prototype.sortBy = function() {
        keyPaths = [];
        for (var i=0,l=arguments.length; i<l; i++) {
            switch (typeof(arguments[i])) {
                case "object": saveKeyPath(arguments[i]); break;
                case "string": saveKeyPath(arguments[i].match(/[+-]|[^.]+/g)); break;
            }
        }
        return this.sort(comparer);
    };    
})();

Uso:

var data = [
    { name: { first: 'Josh', last: 'Jones' }, age: 30 },
    { name: { first: 'Carlos', last: 'Jacques' }, age: 19 },
    { name: { first: 'Carlos', last: 'Dante' }, age: 23 },
    { name: { first: 'Tim', last: 'Marley' }, age: 9 },
    { name: { first: 'Courtney', last: 'Smith' }, age: 27 },
    { name: { first: 'Bob', last: 'Smith' }, age: 30 }
]

data.sortBy('age'); // "Tim Marley(9)", "Carlos Jacques(19)", "Carlos Dante(23)", "Courtney Smith(27)", "Josh Jones(30)", "Bob Smith(30)"

Ordenar por propiedades anidadas con sintaxis de puntos o sintaxis de matriz:

data.sortBy('name.first'); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
data.sortBy(['name', 'first']); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"

Ordenar por múltiples claves:

data.sortBy('name.first', 'age'); // "Bob Smith(30)", "Carlos Jacques(19)", "Carlos Dante(23)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
data.sortBy('name.first', '-age'); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"

Puede bifurcar el repositorio: https://github.com/eneko/Array.sortBy

Eneko Alonso
fuente
Me gusta mucho esta respuesta debido a sortByla sintaxis concisa. Fácil de usar, incluso con campos anidados, manteniendo una gran legibilidad de código. ¡Gracias!
Manfred Urban
3

Con ECMAScript 6, la respuesta de StoBor puede hacerse aún más concisa:

homes.sort((a, b) => a.price - b.price)
CracyD
fuente
3

Orden de precio descendente:

homes.sort((x,y) => {return y.price - x.price})

Orden ascendente de precio:

homes.sort((x,y) => {return x.price - y.price})
revs Arushi Bajpai
fuente
2

Si usa Underscore.js , intente sortBy:

// price is of an integer type
_.sortBy(homes, "price"); 

// price is of a string type
_.sortBy(homes, function(home) {return parseInt(home.price);}); 
Vitalii Fedorenko
fuente
2

Aquí hay una versión ligeramente modificada de implementación elegante del libro "JavaScript: The Good Parts".

NOTA : Esta versión de byes estable . Conserva el orden del primer tipo mientras se realiza el siguiente tipo encadenado.

Le he agregado un isAscendingparámetro. También lo convirtió a ES6estándares y partes buenas "más nuevas" según lo recomendado por el autor.

Puede ordenar el orden ascendente y descendente y en cadena por múltiples propiedades.

const by = function (name, minor, isAscending=true) {
    const reverseMutliplier = isAscending ? 1 : -1;
    return function (o, p) {
        let a, b;
        let result;
        if (o && p && typeof o === "object" && typeof p === "object") {
            a = o[name];
            b = p[name];
            if (a === b) {
                return typeof minor === 'function' ? minor(o, p) : 0;
            }
            if (typeof a === typeof b) {
                result = a < b ? -1 : 1;
            } else {
                result = typeof a < typeof b ? -1 : 1;
            }
            return result * reverseMutliplier;
        } else {
            throw {
                name: "Error",
                message: "Expected an object when sorting by " + name
            };
        }
    };
};

let s = [
    {first: 'Joe',   last: 'Besser'},
    {first: 'Moe',   last: 'Howard'},
    {first: 'Joe',   last: 'DeRita'},
    {first: 'Shemp', last: 'Howard'},
    {first: 'Larry', last: 'Fine'},
    {first: 'Curly', last: 'Howard'}
];

// Sort by: first ascending, last ascending
s.sort(by("first", by("last")));    
console.log("Sort by: first ascending, last ascending: ", s);     // "[
//     {"first":"Curly","last":"Howard"},
//     {"first":"Joe","last":"Besser"},     <======
//     {"first":"Joe","last":"DeRita"},     <======
//     {"first":"Larry","last":"Fine"},
//     {"first":"Moe","last":"Howard"},
//     {"first":"Shemp","last":"Howard"}
// ]

// Sort by: first ascending, last descending
s.sort(by("first", by("last", 0, false)));  
console.log("sort by: first ascending, last descending: ", s);    // "[
//     {"first":"Curly","last":"Howard"},
//     {"first":"Joe","last":"DeRita"},     <========
//     {"first":"Joe","last":"Besser"},     <========
//     {"first":"Larry","last":"Fine"},
//     {"first":"Moe","last":"Howard"},
//     {"first":"Shemp","last":"Howard"}
// ]

codificador mítico
fuente
¿podríamos ordenar el {"first":"Curly","last":"Howard", "property" : {"id" : "1"}}tipo de matriz por id?
Sahu V Kumar
Sí, la función tiene que modificarse ligeramente para incluir un nuevo parámetro, por ejemplo, nestedName. Luego llama bycon name = "property", nestedName = "id"
mythicalcoder
2

Solo para una matriz normal de valores de elementos:

function sortArrayOfElements(arrayToSort) {
    function compareElements(a, b) {
        if (a < b)
            return -1;
        if (a > b)
            return 1;
        return 0;
    }

    return arrayToSort.sort(compareElements);
}

e.g. 1:
var array1 = [1,2,545,676,64,2,24]
output : [1, 2, 2, 24, 64, 545, 676]

var array2 = ["v","a",545,676,64,2,"24"]
output: ["a", "v", 2, "24", 64, 545, 676]

Para una matriz de objetos:

function sortArrayOfObjects(arrayToSort, key) {
    function compareObjects(a, b) {
        if (a[key] < b[key])
            return -1;
        if (a[key] > b[key])
            return 1;
        return 0;
    }

    return arrayToSort.sort(compareObjects);
}

e.g. 1: var array1= [{"name": "User4", "value": 4},{"name": "User3", "value": 3},{"name": "User2", "value": 2}]

output : [{"name": "User2", "value": 2},{"name": "User3", "value": 3},{"name": "User4", "value": 4}]
Umesh
fuente
2

Cree una función y ordene según la entrada usando el código a continuación

var homes = [{

    "h_id": "3",
    "city": "Dallas",
    "state": "TX",
    "zip": "75201",
    "price": "162500"

 }, {

    "h_id": "4",
    "city": "Bevery Hills",
    "state": "CA",
    "zip": "90210",
    "price": "319250"

 }, {

    "h_id": "5",
    "city": "New York",
    "state": "NY",
    "zip": "00010",
    "price": "962500"

 }];

 function sortList(list,order){
     if(order=="ASC"){
        return list.sort((a,b)=>{
            return parseFloat(a.price) - parseFloat(b.price);
        })
     }
     else{
        return list.sort((a,b)=>{
            return parseFloat(b.price) - parseFloat(a.price);
        });
     }
 }

 sortList(homes,'DESC');
 console.log(homes);
Andrew Rayan
fuente
2

Puede usar string1.localeCompare (string2) para comparar cadenas

this.myArray.sort((a,b) => { 
    return a.stringProp.localeCompare(b.stringProp);
});

Tenga en cuenta que localComparees caso en sensible

bradvido
fuente
1

Para ordenar en campo de objeto de matriz múltiple. Ingrese el nombre de su campo en la arrpropmatriz como, ["a","b","c"] luego, pase arrsourcela fuente real del segundo parámetro que queremos ordenar.

function SortArrayobject(arrprop,arrsource){
arrprop.forEach(function(i){
arrsource.sort(function(a,b){
return ((a[i] < b[i]) ? -1 : ((a[i] > b[i]) ? 1 : 0));
});
});
return arrsource;
}
Pradip Talaviya
fuente
1

Necesitarás dos funciones

function desc(a, b) {
 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}

function asc(a, b) {
  return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}

Luego puede aplicar esto a cualquier propiedad de objeto:

 data.sort((a, b) => desc(parseFloat(a.price), parseFloat(b.price)));

let data = [
    {label: "one", value:10},
    {label: "two", value:5},
    {label: "three", value:1},
];

// sort functions
function desc(a, b) {
 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}

function asc(a, b) {
 return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}

// DESC
data.sort((a, b) => desc(a.value, b.value));

document.body.insertAdjacentHTML(
 'beforeend', 
 '<strong>DESCending sorted</strong><pre>' + JSON.stringify(data) +'</pre>'
);

// ASC
data.sort((a, b) => asc(a.value, b.value));

document.body.insertAdjacentHTML(
 'beforeend', 
 '<strong>ASCending sorted</strong><pre>' + JSON.stringify(data) +'</pre>'
);

OzzyCzech
fuente
0

Recientemente escribí una función universal para administrar esto por ti si quieres usarlo.

/**
 * Sorts an object into an order
 *
 * @require jQuery
 *
 * @param object Our JSON object to sort
 * @param type Only alphabetical at the moment
 * @param identifier The array or object key to sort by
 * @param order Ascending or Descending
 *
 * @returns Array
 */
function sortItems(object, type, identifier, order){

    var returnedArray = [];
    var emptiesArray = []; // An array for all of our empty cans

    // Convert the given object to an array
    $.each(object, function(key, object){

        // Store all of our empty cans in their own array
        // Store all other objects in our returned array
        object[identifier] == null ? emptiesArray.push(object) : returnedArray.push(object);

    });

    // Sort the array based on the type given
    switch(type){

        case 'alphabetical':

            returnedArray.sort(function(a, b){

                return(a[identifier] == b[identifier]) ? 0 : (

                    // Sort ascending or descending based on order given
                    order == 'asc' ? a[identifier] > b[identifier] : a[identifier] < b[identifier]

                ) ? 1 : -1;

            });

            break;

        default:

    }

    // Return our sorted array along with the empties at the bottom depending on sort order
    return order == 'asc' ? returnedArray.concat(emptiesArray) : emptiesArray.concat(returnedArray);

}
Brad Bird
fuente
0
homes.sort(function(a, b){
  var nameA=a.prices.toLowerCase(), nameB=b.prices.toLowerCase()
  if (nameA < nameB) //sort string ascending
    return -1 
  if (nameA > nameB)
    return 1
  return 0 //default return value (no sorting)
})
usuario3346960
fuente
0

Hola, después de leer este artículo, hice un sortComparator para mis necesidades, con la funcionalidad de comparar más de un atributo json, y quiero compartirlo con ustedes.

Esta solución solo compara cadenas en orden ascendente, pero la solución puede ampliarse fácilmente para que cada atributo admita: orden inverso, otros tipos de datos, uso de configuración regional, conversión, etc.

var homes = [{

    "h_id": "3",
    "city": "Dallas",
    "state": "TX",
    "zip": "75201",
    "price": "162500"

}, {

    "h_id": "4",
    "city": "Bevery Hills",
    "state": "CA",
    "zip": "90210",
    "price": "319250"

}, {

    "h_id": "5",
    "city": "New York",
    "state": "NY",
    "zip": "00010",
    "price": "962500"

}];

// comp = array of attributes to sort
// comp = ['attr1', 'attr2', 'attr3', ...]
function sortComparator(a, b, comp) {
    // Compare the values of the first attribute
    if (a[comp[0]] === b[comp[0]]) {
        // if EQ proceed with the next attributes
        if (comp.length > 1) {
            return sortComparator(a, b, comp.slice(1));
        } else {
            // if no more attributes then return EQ
            return 0;
        }
    } else {
        // return less or great
        return (a[comp[0]] < b[comp[0]] ? -1 : 1)
    }
}

// Sort array homes
homes.sort(function(a, b) {
    return sortComparator(a, b, ['state', 'city', 'zip']);
});

// display the array
homes.forEach(function(home) {
    console.log(home.h_id, home.city, home.state, home.zip, home.price);
});

y el resultado es

$ node sort
4 Bevery Hills CA 90210 319250
5 New York NY 00010 962500
3 Dallas TX 75201 162500

y otro tipo

homes.sort(function(a, b) {
    return sortComparator(a, b, ['city', 'zip']);
});

con resultado

$ node sort
4 Bevery Hills CA 90210 319250
3 Dallas TX 75201 162500
5 New York NY 00010 962500
George Vrynios
fuente
0

Un código simple:

    var homes = [
        {
            "h_id": "3",
            "city": "Dallas",
            "state": "TX",
            "zip": "75201",
            "price": "162500"
        }, {
            "h_id": "4",
            "city": "Bevery Hills",
            "state": "CA",
            "zip": "90210",
            "price": "319250"
        }, {
            "h_id": "5",
            "city": "New York",
            "state": "NY",
            "zip": "00010",
            "price": "962500"
        }
    ];

    let sortByPrice = homes.sort(function (a, b) 
    {
      return parseFloat(b.price) - parseFloat(a.price);
    });

    for (var i=0; i<sortByPrice.length; i++)
    {
      document.write(sortByPrice[i].h_id+' '+sortByPrice[i].city+' '
       +sortByPrice[i].state+' '
       +sortByPrice[i].zip+' '+sortByPrice[i].price);
      document.write("<br>");
    }

revs rashedcs
fuente
0
 function compareValues(key, order = 'asc') {
  return function innerSort(a, b) {
    if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
      // property doesn't exist on either object
      return 0;
    }

    const varA = (typeof a[key] === 'string')
      ? a[key].toUpperCase() : a[key];
    const varB = (typeof b[key] === 'string')
      ? b[key].toUpperCase() : b[key];

    let comparison = 0;
    if (varA > varB) {
      comparison = 1;
    } else if (varA < varB) {
      comparison = -1;
    }
    return (
      (order === 'desc') ? (comparison * -1) : comparison
    );
  };
}

http://yazilimsozluk.com/sort-array-in-javascript-by-asc-or-desc

usuario1688401
fuente