เรียงลำดับอาร์เรย์ของวัตถุตามค่าคุณสมบัติ


1332

ฉันมีวัตถุต่อไปนี้โดยใช้ AJAX และเก็บไว้ในอาร์เรย์:

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"
    }
];

ฉันจะสร้างฟังก์ชั่นเพื่อเรียงลำดับวัตถุตามpriceคุณสมบัติในลำดับจากน้อยไปมาก หรือ มากไปหาน้อยโดยใช้ JavaScript ได้อย่างไร


วิธีที่เร็วที่สุดคือการใช้โมดูลเรียงลำดับ isomorphic ซึ่งทำงานได้ทั้งในเบราว์เซอร์และโหนดสนับสนุนการป้อนข้อมูลทุกประเภทฟิลด์คำนวณและคำสั่งการเรียงลำดับแบบกำหนดเอง
Lloyd

คำตอบ:


1674

เรียงลำดับบ้านตามราคาในลำดับ:

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

หรือหลังจากรุ่น ES6:

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

เอกสารบางอย่างที่สามารถพบได้ที่นี่


182
คุณสามารถใช้string1.localeCompare(string2)สำหรับการเปรียบเทียบสตริง
bradvido

62
โปรดจำไว้ว่าlocaleCompare()เป็นกรณีที่ไม่สำคัญ (string1 > string2) - (string1 < string2)หากคุณต้องการกรณีที่สำคัญคุณสามารถใช้ ค่าบูลีนจะถูกรวมเป็นจำนวนเต็ม 0 และ 1 เพื่อคำนวณความแตกต่าง
Don Kirkby

2
ขอบคุณสำหรับการอัปเดต @Pointy ฉันจำไม่ได้ว่าพบปัญหานี้ แต่อาจมีการเปลี่ยนแปลงพฤติกรรมในสองสามปีที่ผ่านมา ไม่ว่าlocaleCompare()เอกสารนั้นจะแสดงว่าคุณสามารถระบุได้อย่างชัดเจนว่าคุณต้องการความไวตัวพิมพ์เล็ก - ใหญ่การเรียงลำดับตัวเลขและตัวเลือกอื่น ๆ
Don Kirkby

2
@ sg28 ฉันคิดว่าคุณเข้าใจผิดคำอธิบาย MDN มันไม่ได้บอกว่าฟังก์ชั่นการจัดเรียงที่ไม่น่าเชื่อถือก็บอกว่ามันไม่ได้มีเสถียรภาพ ฉันเข้าใจว่าทำไมสิ่งนี้ถึงทำให้เกิดความสับสน แต่นั่นไม่ใช่การอ้างสิทธิ์ว่าไม่เหมาะสำหรับการใช้งาน ในบริบทของขั้นตอนวิธีการเรียงลำดับคำที่มั่นคงมีความหมายเฉพาะเจาะจง - ว่า "เท่ากับ" องค์ประกอบในรายการจะเรียงตามลำดับเช่นเดียวกับในการป้อนข้อมูล สิ่งนี้ไม่เกี่ยวข้องกับแนวคิดของโค้ดที่ไม่เสถียร (เช่นยังไม่พร้อมใช้งาน)
Stobor

1
หากคุณต้องการเรียงลำดับตามค่าสตริงที่ระบุตัวอย่างเช่นตามเมืองคุณสามารถใช้: this.homes.sort ((ปัจจุบัน, ถัดไป) => {return current.city.localeCompare (next.city)});
Jorge Valvert

675

นี่คือเวอร์ชันที่ยืดหยุ่นมากขึ้นซึ่งช่วยให้คุณสร้างฟังก์ชั่นการเรียงลำดับที่ใช้ซ้ำได้และเรียงลำดับตามฟิลด์ใด ๆ

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()
)));


7
nickb - คุณกำลังอ่านรหัสผิด sort_byทำงานใน O (1) และส่งคืนฟังก์ชันที่ใช้โดยการเรียงลำดับในตัว (O (N log N)) เพื่อเปรียบเทียบรายการในรายการ ความซับซ้อนทั้งหมดคือ O (n log n) * O (1) ซึ่งลดลงเป็น O (n log n) หรือเหมือนกับการจัดเรียงอย่างรวดเร็ว
Triptych

1
สิ่งหนึ่งที่ฉันมีคือว่า reverse = false มันจะเรียงลำดับตัวเลขเป็น 1,2,3,4 ... แต่ Strings เป็น z, y, x ...
Abby

4
การปรับปรุงเล็ก ๆ น้อย ๆ :var key = primer ? function (x) { return primer(x[field]); } : function (x) { return x[field]; }
ErikE

6
ในขณะที่[1,-1][+!!reverse]ดูดีมันเป็นสิ่งที่น่ากลัวที่จะทำ หากผู้ใช้ไม่สามารถเรียกวิธีการของคุณได้อย่างถูกต้องให้ลงโทษเขาไม่พยายามทำให้เข้าใจอย่างใดไม่ว่าจะเกิดอะไรขึ้น
Ingo Bürk

2
จะเป็นการดีกว่าหรือไม่ที่จะเตรียมข้อมูลต้นฉบับซึ่งจะทำให้การแยกวิเคราะห์ติดต่อกันเมื่อเห็นได้ชัดว่าข้อมูลต้นฉบับต้องการการปรับแต่งเล็กน้อย
Gerrit Brink

134

ในการจัดเรียงคุณต้องสร้างฟังก์ชั่นเปรียบเทียบเพื่อรับสองอาร์กิวเมนต์ จากนั้นเรียกใช้ฟังก์ชัน sort พร้อมกับฟังก์ชั่นตัวเปรียบเทียบดังนี้

// 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);

หากคุณต้องการเรียงลำดับจากน้อยไปมากสลับนิพจน์ในแต่ละด้านของเครื่องหมายลบ


3
และนี่คือการอ้างอิงที่อธิบายถึงหัวข้อแทนที่จะพูดว่า "มันซับซ้อนเกินไปคุณจะไม่เข้าใจมัน": developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
......

51

สำหรับการเรียงลำดับสตริงในกรณีที่บางคนต้องการมัน

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;
}));


38

หากคุณมีเบราว์เซอร์ที่สอดคล้องกับES6คุณสามารถใช้:

ความแตกต่างระหว่างลำดับการเรียงจากน้อยไปมากและจากมากไปหาน้อยคือเครื่องหมายของค่าที่ส่งคืนโดยฟังก์ชันเปรียบเทียบของคุณ:

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

นี่คือข้อมูลโค้ดที่ใช้งานได้:

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);


22

คุณต้องการจัดเรียงใน Javascript ใช่ไหม สิ่งที่คุณต้องการเป็นฟังก์ชั่นsort() ในกรณีนี้คุณต้องเขียนฟังก์ชั่นตัวเปรียบเทียบและส่งไปsort()ให้ดังนั้นสิ่งนี้:

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));

เครื่องมือเปรียบเทียบของคุณใช้หนึ่งในแฮชที่ซ้อนกันภายในอาร์เรย์และตัดสินใจว่าอันไหนที่สูงกว่าโดยการตรวจสอบฟิลด์ "ราคา"


21

ฉันแนะนำGitHub: Array sortBy - การใช้งานที่ดีที่สุดของsortByวิธีการที่ใช้การแปลง Schwartzian

แต่สำหรับตอนนี้เรากำลังจะลองวิธีนี้สรุปสาระสำคัญ: SortBy-old.js
ลองสร้างวิธีการเรียงลำดับอาร์เรย์ที่สามารถจัดเรียงวัตถุตามคุณสมบัติบางอย่าง

การสร้างฟังก์ชั่นการเรียงลำดับ

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));
    });
  };

}());

การตั้งค่าข้อมูลที่ไม่เรียงลำดับ

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"}
];

ใช้มัน

จัดเรียงอาร์เรย์โดย"date"เป็นString

// 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"}

หากคุณต้องการเพิกเฉยต่อตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ให้ตั้งค่าการparserโทรกลับ:

// 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" }

หากคุณต้องการแปลง"date"ฟิลด์เป็นDateประเภท:

// 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" }

ที่นี่คุณสามารถเล่นกับรหัส: jsbin.com/lesebi

ขอบคุณ@Ozeshจากข้อเสนอแนะของเขาปัญหาที่เกี่ยวข้องกับคุณสมบัติที่มีค่าเท็จได้รับการแก้ไขแล้ว


สิ่งนี้ดูเหมือนว่าจะแตกเมื่อเขตข้อมูลเป็นโมฆะ
TSNev

ในกรณีที่คุณเรียงลำดับตัวเลขและพบ '0' ระหว่างอาร์เรย์ของออบเจ็กต์คุณอาจสังเกตเห็นว่าการแบ่งรหัสข้างต้น .. นี่คือการแก้ไขอย่างรวดเร็วสำหรับที่: var checkNaN = function (value) { return Number.isNaN(Number(value)) ? 0 : value; } ตามด้วย: ฟังก์ชั่นกลับ (อาร์เรย์, 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

ใช้lodash.sortBy (คำแนะนำการใช้ commonjs คุณยังสามารถใส่สคริปต์รวม - แท็กสำหรับ cdnที่ด้านบนของ html ของคุณ)

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

เรียงลำดับจากมากไปน้อย

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

เรียงลำดับขึ้น

var ascendingOrder = sortBy( homes, 'price' );

1
หรือconst sortBy = require('lodash/sortBy'); let calendars = sortBy(calendarListResponse.items, cal => cal.summary);
mpen

ไม่แน่ใจว่าโหลดแคชเปลี่ยนไปเมื่อเร็ว ๆ นี้โดยตอนนี้ชื่อของมันคือ OrderByimport { orderBy } from 'lodash'; ... ... return orderBy ( rows, 'fieldName' ).reverse();
montelof

8

สิ่งนี้สามารถทำได้โดยใช้ฟังก์ชันการเรียงลำดับบรรทัดเดียว ()อย่างง่าย เรียกใช้ข้อมูลโค้ดด้านล่างเพื่อดูตัวอย่าง

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);


8

ฉันมาสายนิดหน่อยสำหรับงานปาร์ตี้ แต่ข้างล่างนี้เป็นตรรกะในการเรียงลำดับของฉัน

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

6

ในขณะที่ฉันทราบว่า OP ต้องการเรียงลำดับตัวเลขจำนวนหนึ่งคำถามนี้ถูกทำเครื่องหมายเป็นคำตอบสำหรับคำถามที่คล้ายกันเกี่ยวกับสตริง จากข้อเท็จจริงดังกล่าวคำตอบข้างต้นไม่ได้พิจารณาเรียงลำดับข้อความที่มีความสำคัญ คำตอบส่วนใหญ่จะใช้ค่าสตริงและแปลงเป็นตัวพิมพ์ใหญ่ / ตัวพิมพ์เล็กแล้วเรียงลำดับทางเดียว ข้อกำหนดที่ฉันปฏิบัติตามนั้นเรียบง่าย:

  • เรียงลำดับตัวอักษร AZ
  • ค่าตัวพิมพ์ใหญ่ของคำเดียวกันควรมาก่อนค่าตัวพิมพ์เล็ก
  • ค่าตัวอักษรเดียวกัน (A / a, B / b) ควรจัดกลุ่มไว้ด้วยกัน

สิ่งที่ผมคาดหวังแต่คำตอบข้างต้นผลตอบแทน[ A, a, B, b, C, c ] A, B, C, a, b, cฉันเกาหัวของฉันบนนี้นานกว่าที่ฉันต้องการ (ซึ่งเป็นเหตุผลที่ฉันโพสต์นี้ด้วยความหวังว่ามันจะช่วยอย่างน้อยหนึ่งคนอื่น ๆ ) ในขณะที่ผู้ใช้สองคนพูดถึงlocaleCompareฟังก์ชั่นในความคิดเห็นสำหรับคำตอบที่ทำเครื่องหมายไว้ฉันไม่เห็นว่าจนกระทั่งหลังจากฉันสะดุดฟังก์ชั่นขณะค้นหา หลังจากอ่านเอกสาร String.prototype.localeCompare ()ฉันสามารถคิดสิ่งนี้ได้:

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" ]

สิ่งนี้บอกให้ฟังก์ชันเรียงลำดับค่าตัวพิมพ์ใหญ่ก่อนค่าตัวพิมพ์เล็ก พารามิเตอร์ที่สองในlocaleCompareฟังก์ชั่นคือการกำหนดสถานที่ แต่ถ้าคุณปล่อยให้มันเป็นundefinedมันโดยอัตโนมัติตัวเลขสถานที่สำหรับคุณ

สิ่งนี้ทำงานเหมือนกันสำหรับการเรียงลำดับอาร์เรย์ของวัตถุเช่นกัน:

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" }));

5

คุณสามารถใช้sortวิธีการจาวาสคริปต์กับฟังก์ชั่นการโทรกลับ:

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);

4

นี่คือสุดยอดของคำตอบทั้งหมดข้างต้น

การตรวจสอบ Fiddle: 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();

        }));
    }


}

คุณช่วยอธิบายความสำคัญของการมี * (rev ได้อย่างไร -1: 1);
TechTurtle

นั่นคือการกลับคำสั่งซื้อ (จากน้อยไปมากและจากมากไปน้อย) ส่วน rev จะพลิกผลลัพธ์ปกติเมื่ออาร์กิวเมนต์ rev เป็นจริง ไม่เช่นนั้นมันจะคูณด้วย 1 ซึ่งไม่ทำอะไรเลยเมื่อตั้งค่ามันจะทวีคูณผลลัพธ์ด้วย -1 จึงเป็นการพลิกผลลัพธ์
บ๊อบ

3

ฉันยังทำงานกับการให้คะแนนและการเรียงลำดับหลายฟิลด์:

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);
});

ผลลัพธ์

[
    {"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}
]

3

ในขณะที่มันเป็นบิตของ overkill เพียงแค่การเรียงลำดับอาเรย์เดียวฟังก์ชั่นต้นแบบนี้ช่วยให้การจัดเรียง Javascript อาร์เรย์โดยใช้คีย์ใด ๆ ในลำดับขึ้นหรือลงรวมถึงคีย์ที่ซ้อนกันโดยใช้dotไวยากรณ์

(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);
    };    
})();

การใช้งาน:

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)"

เรียงลำดับตามคุณสมบัติที่ซ้อนกันด้วย dot-syntax หรือ array-syntax:

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)"

เรียงตามปุ่มหลาย ๆ ปุ่ม:

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)"

คุณสามารถแยก repo: https://github.com/eneko/Array.sortBy


ฉันชอบคำตอบนี้มากเพราะsortByไวยากรณ์ที่รัดกุม ง่ายต่อการใช้ –even พร้อมซ้อนฟิลด์ - ในขณะที่ยังคงสามารถอ่านโค้ดได้อย่างยอดเยี่ยม ขอบคุณ!
Manfred Urban

3

ด้วยคำตอบของ ECMAScript 6 StoBor สามารถทำได้อย่างกระชับยิ่งขึ้น:

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

3

จากมากไปน้อยราคา:

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

เรียงจากน้อยไปมากราคา:

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

2

สำหรับการเรียงลำดับอาร์เรย์คุณต้องกำหนดฟังก์ชันตัวเปรียบเทียบ ฟังก์ชั่นนี้จะแตกต่างกันไปตามรูปแบบการเรียงลำดับหรือคำสั่งที่คุณต้องการ (เช่นขึ้นหรือลง)

ให้สร้างฟังก์ชั่นบางอย่างที่เรียงลำดับอาร์เรย์จากน้อยไปมากหรือมากไปน้อยและมีวัตถุหรือสตริงหรือค่าตัวเลข

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']);
}

เรียงลำดับตัวเลข (เรียงตามตัวอักษรและขึ้น):

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

เรียงลำดับตัวเลข (เรียงตามตัวอักษรและจากมากไปน้อย):

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

เรียงลำดับตัวเลข (ตัวเลขและเรียงจากน้อยไปมาก):

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

เรียงหมายเลข (ตัวเลขและจากมากไปน้อย):

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

ข้างต้นใช้ sorterPriceAsc และวิธี sorterPriceDes กับอาร์เรย์ของคุณด้วยคีย์ที่ต้องการ

homes.sort(sorterPriceAsc()) or homes.sort(sorterPriceDes())


2

นี่คือเวอร์ชันที่ปรับเปลี่ยนเล็กน้อยของการใช้งานที่หรูหราจากหนังสือ "JavaScript: The Good Parts"

หมายเหตุ : รุ่นนี้byมีเสถียรภาพ มันรักษาลำดับของการเรียงลำดับแรกในขณะที่ดำเนินการเรียงลำดับที่ถูกล่ามโซ่ต่อไป

ฉันได้เพิ่มisAscendingพารามิเตอร์เข้าไป แปลงให้เป็นES6มาตรฐานและชิ้นส่วนที่ดี "ใหม่กว่า" ตามที่ผู้เขียนแนะนำไว้

คุณสามารถเรียงลำดับจากน้อยไปมากและจากมากไปน้อยและเรียงลำดับตามคุณสมบัติหลายรายการ

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"}
// ]


เราสามารถจัดเรียง{"first":"Curly","last":"Howard", "property" : {"id" : "1"}}ประเภทของอาร์เรย์ตามรหัสได้หรือไม่?
Vishal Kumar Sahu

ใช่ฟังก์ชั่นจะต้องมีการปรับเปลี่ยนเล็กน้อยเพื่อใช้ในพารามิเตอร์ใหม่พูด nestedName จากนั้นคุณโทรหาbyชื่อ = "property", nestedName = "id"
mythicalcoder

2

สำหรับอาร์เรย์ขององค์ประกอบค่าปกติเท่านั้น:

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]

สำหรับอาร์เรย์ของวัตถุ:

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}]

2

สร้างฟังก์ชั่นและเรียงลำดับตามอินพุตโดยใช้โค้ดด้านล่าง

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);

2

คุณสามารถใช้ string1.localeCompare (string2) สำหรับการเปรียบเทียบสตริง

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

ทราบว่าlocalCompareเป็นกรณีในความละเอียดอ่อน


1

สำหรับการจัดเรียงในฟิลด์วัตถุอาร์เรย์หลายชุด ป้อนชื่อเขตข้อมูลของคุณในarrpropอาร์เรย์เหมือน["a","b","c"] แล้วผ่านพารามิเตอร์ที่สองarrsourceที่มาจริงที่เราต้องการเรียงลำดับ

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;
}

1

คุณจะต้องมีสองฟังก์ชั่น

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;
}

จากนั้นคุณสามารถใช้สิ่งนี้กับคุณสมบัติของวัตถุใด ๆ :

 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>'
);


0

ฉันเพิ่งเขียนฟังก์ชันสากลเพื่อจัดการสิ่งนี้ให้คุณหากคุณต้องการใช้

/**
 * 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);

}

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)
})

0

สวัสดีหลังจากอ่านบทความนี้ฉันได้จัดเรียงตัวเปรียบเทียบสำหรับความต้องการของฉันด้วยฟังก์ชันการทำงานเพื่อเปรียบเทียบมากกว่าหนึ่งคุณลักษณะ json และฉันต้องการแบ่งปันกับคุณ

โซลูชันนี้เปรียบเทียบเฉพาะสตริงตามลำดับจากน้อยไปหามาก แต่โซลูชันสามารถขยายได้ง่ายสำหรับแต่ละแอตทริบิวต์เพื่อสนับสนุน: การเรียงลำดับย้อนกลับประเภทข้อมูลอื่น ๆ เพื่อใช้สถานที่เกิดเหตุหล่อ ฯลฯ

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);
});

และผลลัพธ์คือ

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

และประเภทอื่น

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

กับผลลัพธ์

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

0

รหัสง่าย ๆ :

    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>");
    }


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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.