JavaScript按属性的数组值

时间:2016-08-19 18:55:03

标签: javascript sorting

我只是想澄清一下,这个问题与普通的“如何按属性排序对象数组有点不同。”

我创建了一个对对象数组进行排序的函数。目标是按价格排序,但保持具有相同价格的对象按航空公司属性的第一个元素按字母顺序排序。它适用于下面的数组,但它不会使它们按字母顺序排列在函数下面的大数据样本中。任何人都可以帮助弄清楚这里出了什么问题?他们按价格排序,但不知何故不保留字母顺序。例如,显示的第一个对象是“ZP”,但它不应该是。

使用此plunkr link

可能更容易玩

var arr = [
  {"airline": ["AA"], "price": 9},
  {"airline": ["AA"], "price": 4},
  {"airline": ["DA"], "price": 5},
  {"airline": ["BA"], "price": 5},
  {"airline": ["ZA"], "price": 5},
  {"airline": ["AD"], "price": 5},
  {"airline": ["FC"], "price": 2},
  {"airline": ["CU"], "price": 4},
  {"airline": ["EA"], "price": 1}
];

var dom = document.getElementById('data');

// This works
// dom.innerHTML = JSON.stringify(sortByProp(arr, 'airline', 'price'), null, 2);

// name is to sort on a prop alphabetically by default
function sortByProp(arr, name, prop) {
  var mapped = arr;

  if (Array.isArray(arr[0][name])) {
    mapped = arr.map(function(obj) {
      var name1 = obj[name][0];
      obj[name] = name1;
      return obj;
    });
  }

  var others = [];

  var filtered = mapped.filter(function(object) {
    if (object.hasOwnProperty(prop) && object.hasOwnProperty(name)) {
      return object;
    }
    else {
      var other = arr.splice(arr.indexOf(object), 1)[0];
      others.push(other);
    }
  });

  var sortedByName = filtered.sort(function(obj1, obj2) {
    return obj1[name].toUpperCase().localeCompare(obj2[name].toUpperCase());
  });

  if (typeof sortedByName[0][prop] === 'string') {
    return sortedByName.concat(others);
  }
  else {
    return sortedByName.sort(function(a, b) {
      return a[prop] - b[prop];
    });
  }
}

var flights = [{
    "airline": ["ZP"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "680",
    "price": 1114,
    "duration": 685,
    "stops": ["KEF"],
    "returnOptions": [{
      "airline": ["FI"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "543",
      "duration": 755,
      "stops": ["KEF"]
    }]
  }, {
    "airline": ["GB"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "680",
    "price": 1114,
    "duration": 685,
    "stops": ["KEF"],
    "returnOptions": [{
      "airline": ["FI"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "543",
      "duration": 765,
      "stops": ["KEF"]
    }]
  }, {
    "airline": ["FI"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "680",
    "price": 1114,
    "duration": 685,
    "stops": ["KEF"],
    "returnOptions": [{
      "airline": ["FI"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "541",
      "duration": 1125,
      "stops": ["KEF"]
    }]
  }, {
    "airline": ["AC"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "680",
    "price": 1114,
    "duration": 685,
    "stops": ["KEF"],
    "returnOptions": [{
      "airline": ["FI"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "541",
      "duration": 1135,
      "stops": ["KEF"]
    }]
  }, {
    "airline": ["FI"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "7637",
    "price": 1761,
    "duration": 835,
    "stops": ["PDX", "KEF"],
    "returnOptions": [{
      "airline": ["FI"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "543",
      "duration": 755,
      "stops": ["KEF"]
    }]
  }, {
    "airline": ["FI"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "7637",
    "price": 1761,
    "duration": 835,
    "stops": ["PDX", "KEF"],
    "returnOptions": [{
      "airline": ["FI"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "543",
      "duration": 765,
      "stops": ["KEF"]
    }]
  }, {
    "airline": ["FI"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "7637",
    "price": 1761,
    "duration": 835,
    "stops": ["PDX", "KEF"],
    "returnOptions": [{
      "airline": ["FI"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "541",
      "duration": 1125,
      "stops": ["KEF"]
    }]
  }, {
    "airline": ["FI"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "7637",
    "price": 1761,
    "duration": 835,
    "stops": ["PDX", "KEF"],
    "returnOptions": [{
      "airline": ["FI"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "541",
      "duration": 1135,
      "stops": ["KEF"]
    }]
  }, {
    "airline": ["EI"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "5267",
    "price": 1807,
    "duration": 980,
    "stops": ["BOS", "DUB"],
    "returnOptions": [{
      "airline": ["EI"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "529",
      "duration": 1350,
      "stops": ["DUB", "LHR"]
    }]
  }, {
    "airline": ["UA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "8618",
    "price": 2206,
    "duration": 770,
    "stops": ["YYZ"],
    "returnOptions": [{
      "airline": ["SN"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3632",
      "duration": 1285,
      "stops": ["BRU", "YYZ"]
    }]
  }, {
    "airline": ["AC"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "542",
    "price": 2206,
    "duration": 770,
    "stops": ["YYZ"],
    "returnOptions": [{
      "airline": ["SN"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3632",
      "duration": 1285,
      "stops": ["BRU", "YYZ"]
    }]
  }, {
    "airline": ["UA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "278",
    "price": 2208,
    "duration": 835,
    "stops": ["ORD"],
    "returnOptions": [{
      "airline": ["SN"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3632",
      "duration": 1285,
      "stops": ["BRU", "YYZ"]
    }]
  }, {
    "airline": ["UA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "419",
    "price": 2208,
    "duration": 837,
    "stops": ["IAD"],
    "returnOptions": [{
      "airline": ["SN"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3632",
      "duration": 1285,
      "stops": ["BRU", "YYZ"]
    }]
  }, {
    "airline": ["AC"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "8090",
    "price": 2212,
    "duration": 925,
    "stops": ["YVR", "YUL"],
    "returnOptions": [{
      "airline": ["SN"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3628",
      "duration": 1210,
      "stops": ["BRU", "ORD"]
    }]
  }, {
    "airline": ["AC"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "8090",
    "price": 2212,
    "duration": 925,
    "stops": ["YVR", "YUL"],
    "returnOptions": [{
      "airline": ["SN"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3628",
      "duration": 1210,
      "stops": ["BRU", "ORD"]
    }]
  }, {
    "airline": ["UA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "8618",
    "price": 2219,
    "duration": 770,
    "stops": ["YYZ"],
    "returnOptions": [{
      "airline": ["SN"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3628",
      "duration": 1210,
      "stops": ["BRU", "ORD"]
    }]
  }, {
    "airline": ["AC"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "542",
    "price": 2219,
    "duration": 770,
    "stops": ["YYZ"],
    "returnOptions": [{
      "airline": ["SN"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3628",
      "duration": 1210,
      "stops": ["BRU", "ORD"]
    }]
  }, {
    "airline": ["UA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "8618",
    "price": 2219,
    "duration": 770,
    "stops": ["YYZ"],
    "returnOptions": [{
      "airline": ["SN"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3632",
      "duration": 1240,
      "stops": ["BRU", "IAD"]
    }]
  }, {
    "airline": ["AC"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "542",
    "price": 2219,
    "duration": 770,
    "stops": ["YYZ"],
    "returnOptions": [{
      "airline": ["SN"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3632",
      "duration": 1240,
      "stops": ["BRU", "IAD"]
    }]
  }, {
    "airline": ["AC"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "542",
    "price": 2219,
    "duration": 770,
    "stops": ["YYZ"],
    "returnOptions": [{
      "airline": ["SN"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3628",
      "duration": 1315,
      "stops": ["BRU", "IAD"]
    }]
  }, {
    "airline": ["UA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "278",
    "price": 2221,
    "duration": 835,
    "stops": ["ORD"],
    "returnOptions": [{
      "airline": ["SN"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3628",
      "duration": 1210,
      "stops": ["BRU", "ORD"]
    }]
  }, {
    "airline": ["UA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "419",
    "price": 2221,
    "duration": 837,
    "stops": ["IAD"],
    "returnOptions": [{
      "airline": ["SN"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3628",
      "duration": 1210,
      "stops": ["BRU", "ORD"]
    }]
  }, {
    "airline": ["UA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "278",
    "price": 2221,
    "duration": 835,
    "stops": ["ORD"],
    "returnOptions": [{
      "airline": ["SN"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3632",
      "duration": 1240,
      "stops": ["BRU", "IAD"]
    }]
  }, {
    "airline": ["UA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "419",
    "price": 2221,
    "duration": 837,
    "stops": ["IAD"],
    "returnOptions": [{
      "airline": ["SN"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3632",
      "duration": 1240,
      "stops": ["BRU", "IAD"]
    }]
  }, {
    "airline": ["UA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "213",
    "price": 2221,
    "duration": 875,
    "stops": ["SFO"],
    "returnOptions": [{
      "airline": ["SN"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3628",
      "duration": 1210,
      "stops": ["BRU", "ORD"]
    }]
  }, {
    "airline": ["UA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "213",
    "price": 2221,
    "duration": 875,
    "stops": ["SFO"],
    "returnOptions": [{
      "airline": ["SN"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3632",
      "duration": 1240,
      "stops": ["BRU", "IAD"]
    }]
  }, {
    "airline": ["DL"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "32",
    "price": 2249,
    "duration": 606,
    "returnOptions": [{
      "airline": ["DL"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "33",
      "duration": 639
    }]
  }, {
    "airline": ["AF"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "3653",
    "price": 2249,
    "duration": 606,
    "returnOptions": [{
      "airline": ["AF"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "3622",
      "duration": 639
    }]
  }, {
    "airline": ["AA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "44",
    "price": 2249,
    "duration": 850,
    "returnOptions": [{
      "airline": ["AA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "45",
      "duration": 1181
    }]
  }, {
    "airline": ["AC"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "8090",
    "price": 2256,
    "duration": 925,
    "stops": ["YVR", "YUL"],
    "returnOptions": [{
      "airline": ["AC"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "881",
      "duration": 1150,
      "stops": ["YYZ"]
    }]
  }, {
    "airline": ["UA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "213",
    "price": 2278,
    "duration": 875,
    "stops": ["SFO"],
    "returnOptions": [{
      "airline": ["UA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "914",
      "duration": 1020,
      "stops": ["IAD"]
    }]
  }, {
    "airline": ["IB"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "4602",
    "price": 2302,
    "duration": 1165,
    "stops": ["LGW"],
    "returnOptions": [{
      "airline": ["IB"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "4115",
      "duration": 1153,
      "stops": ["ORD"]
    }]
  }, {
    "airline": ["BA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "4924",
    "price": 2306,
    "duration": 1306,
    "stops": ["ORD"],
    "returnOptions": [{
      "airline": ["BA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "315",
      "duration": 725,
      "stops": ["LHR"]
    }]
  }, {
    "airline": ["AA", "BA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "1097",
    "price": 2306,
    "duration": 1310,
    "stops": ["ORD"],
    "returnOptions": [{
      "airline": ["BA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "315",
      "duration": 725,
      "stops": ["LHR"]
    }]
  }, {
    "airline": ["BA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "4924",
    "price": 2306,
    "duration": 1306,
    "stops": ["ORD"],
    "returnOptions": [{
      "airline": ["BA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "309",
      "duration": 840,
      "stops": ["LHR"]
    }]
  }, {
    "airline": ["AA", "BA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "1097",
    "price": 2306,
    "duration": 1310,
    "stops": ["ORD"],
    "returnOptions": [{
      "airline": ["BA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "309",
      "duration": 840,
      "stops": ["LHR"]
    }]
  }, {
    "airline": ["KL"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "6014",
    "price": 2343,
    "duration": 762,
    "stops": ["AMS"],
    "returnOptions": [{
      "airline": ["KL"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "1230",
      "duration": 758,
      "stops": ["AMS"]
    }]
  }, {
    "airline": ["BA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "48",
    "price": 2355,
    "duration": 705,
    "stops": ["LHR"],
    "returnOptions": [{
      "airline": ["BA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "315",
      "duration": 725,
      "stops": ["LHR"]
    }]
  }, {
    "airline": ["BA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "52",
    "price": 2355,
    "duration": 740,
    "stops": ["LHR"],
    "returnOptions": [{
      "airline": ["BA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "315",
      "duration": 725,
      "stops": ["LHR"]
    }]
  }, {
    "airline": ["BA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "48",
    "price": 2355,
    "duration": 785,
    "stops": ["LHR"],
    "returnOptions": [{
      "airline": ["BA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "315",
      "duration": 725,
      "stops": ["LHR"]
    }]
  }, {
    "airline": ["BA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "48",
    "price": 2355,
    "duration": 705,
    "stops": ["LHR"],
    "returnOptions": [{
      "airline": ["BA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "309",
      "duration": 840,
      "stops": ["LHR"]
    }]
  }, {
    "airline": ["BA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "52",
    "price": 2355,
    "duration": 855,
    "stops": ["LHR"],
    "returnOptions": [{
      "airline": ["BA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "315",
      "duration": 725,
      "stops": ["LHR"]
    }]
  }, {
    "airline": ["BA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "52",
    "price": 2355,
    "duration": 740,
    "stops": ["LHR"],
    "returnOptions": [{
      "airline": ["BA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "309",
      "duration": 840,
      "stops": ["LHR"]
    }]
  }, {
    "airline": ["BA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "48",
    "price": 2355,
    "duration": 785,
    "stops": ["LHR"],
    "returnOptions": [{
      "airline": ["BA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "309",
      "duration": 840,
      "stops": ["LHR"]
    }]
  }, {
    "airline": ["BA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "48",
    "price": 2355,
    "duration": 950,
    "stops": ["LHR"],
    "returnOptions": [{
      "airline": ["BA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "315",
      "duration": 725,
      "stops": ["LHR"]
    }]
  }, {
    "airline": ["BA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "52",
    "price": 2355,
    "duration": 855,
    "stops": ["LHR"],
    "returnOptions": [{
      "airline": ["BA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "309",
      "duration": 840,
      "stops": ["LHR"]
    }]
  }, {
    "airline": ["BA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "52",
    "price": 2355,
    "duration": 1020,
    "stops": ["LHR"],
    "returnOptions": [{
      "airline": ["BA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "315",
      "duration": 725,
      "stops": ["LHR"]
    }]
  }, {
    "airline": ["BA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "48",
    "price": 2355,
    "duration": 950,
    "stops": ["LHR"],
    "returnOptions": [{
      "airline": ["BA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "309",
      "duration": 840,
      "stops": ["LHR"]
    }]
  }, {
    "airline": ["BA"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "52",
    "price": 2355,
    "duration": 1100,
    "stops": ["LHR"],
    "returnOptions": [{
      "airline": ["BA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "315",
      "duration": 725,
      "stops": ["LHR"]
    }]
  }, {
    "airline": ["AB"],
    "arrivalStation": "CDG",
    "departureStation": "SEA",
    "flightNumber": "48",
    "price": 2355,
    "duration": 1120,
    "stops": ["LHR"],
    "returnOptions": [{
      "airline": ["BA"],
      "arrivalStation": "SEA",
      "departureStation": "CDG",
      "flightNumber": "315",
      "duration": 725,
      "stops": ["LHR"]
    }]
  }];

// This sorts by price but they are not in alphabetical order
dom.innerHTML = JSON.stringify(sortByProp(flights, 'airline', 'price'), null, 2);
  <body>
    <pre id="data"></pre>
  </body>

Link to plunkr code

1 个答案:

答案 0 :(得分:1)

你可以使用Array#sort这样的回调:

flights.sort(function (a, b) {
    return a.price - b.price || a.airline[0].localeCompare(b.airline[0]);
});