对JavaScript中除一个元素以外的数组进行排序

时间:2018-07-27 11:39:41

标签: javascript arrays sorting

我有一个数组,正在对其进行排序,但是我需要对除数组中一个元素之外的所有元素进行排序。

我的数组是:

var Comparison = [
    {key: "None", value: "None"},
    {key:"Geographical Area", value:"Geographical_Area"},
    {key:"Forests", value:"Forests"},
    {key:"Barren Unculturable Land", value:"Barren_Unculturable_Land"},
    {key:"Land put to Non agricultural use", value:"Land_put_to_Non_agricultural_use"},
    {key:"Land Area", value:"Land_Area"},
    {key:"Water Area", value:"Water_Area"},
    {key:"Culturable Waste", value:"Culturable_Waste"},
    {key:"Permanent Pastures", value:"Permanent_Pastures"},
    {key:"Land under Tree Crops", value:"Land_under_Tree_Crops"},
    {key:"Fallow Land excl Current Fallow", value:"Fallow_Land_excl_Current_Fallow"},
    {key:"Current Fallow", value:"Current_Fallow"},
    {key:"Total Unculturable Land", value:"Total_Unculturable_Land"},
    {key:"Net Sown Area", value:"Net_Sown_Area"},
    {key:"Gross Sown Area", value:"Gross_Sown_Area"},
    {key:"Cropping Intensity", value:"Cropping_Intensity"} ];

我正在使用以下代码对该数组进行排序:

var Comparison_sort = this.Comparison.sort(function (a, b) {
  if (a.key < b.key)
      return -1;
  if (a.key > b.key)
      return 1;
  return 0;
});

这对我的数组进行了完美排序,但是我希望其中一个元素位于顶部,这意味着我的元素None应该位于顶部,并对所有其他元素进行排序。

例如,我得到以下结果:

   {key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}
   {key: "Cropping Intensity", value: "Cropping_Intensity"}
   {key: "Culturable Waste", value: "Culturable_Waste"}
    ....
   {key: "None", value: "None"}

但是我想要这样的结果:

   {key: "None", value: "None"}
   {key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}
   {key: "Cropping Intensity", value: "Cropping_Intensity"}
   {key: "Culturable Waste", value: "Culturable_Waste"}
    ....

我看到了一个答案, Sort array in TypeScript ,但是我无法使用此答案解决我的问题。

10 个答案:

答案 0 :(得分:16)

var Comparison_sort = this.Comparison.sort(function (a, b) {
  if(a.key == b.key) return 0;
  if (a.key == 'None') return -1;
  if (b.key == 'None') return 1;

  if (a.key < b.key)
      return -1;
  if (a.key > b.key)
      return 1;
  return 0;
});

告诉“定期进行排序,除非密钥为空,这意味着它必须先行。”

答案 1 :(得分:8)

不花哨,但是一种非常简单的方法是删除特殊元素,对数组进行排序,然后将特殊对象插入所需的任何索引。

var Comparison = [{ key: "None", value: "None" }, { key: "Geographical Area",value: "Geographical_Area" }, { key: "Forests", value: "Forests" }, { key: "Barren Unculturable Land", value: "Barren_Unculturable_Land" }, { key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use" }, { key: "Land Area", value: "Land_Area" }, { key: "Water Area", value: "Water_Area" }, { key: "Culturable Waste", value: "Culturable_Waste" }, { key: "Permanent Pastures", value: "Permanent_Pastures" }, { key: "Land under Tree Crops", value: "Land_under_Tree_Crops" }, { key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow" }, { key: "Current Fallow", value: "Current_Fallow" }, { key: "Total Unculturable Land", value: "Total_Unculturable_Land" }, { key: "Net Sown Area", value: "Net_Sown_Area" }, { key: "Gross Sown Area", value: "Gross_Sown_Area" }, { key: "Cropping Intensity", value: "Cropping_Intensity" },];

const idx = Comparison.findIndex(a => a.key === 'None');
const none = Comparison.splice(idx, 1);
Comparison.sort((a, b) => a.key.localeCompare(b.key));
Comparison.splice(0,0, none[0]);

console.log(Comparison);

为避免没有特殊或多个特殊元素问题:

var Comparison = [{ key: "None", value: "None" }, { key: "Geographical Area",value: "Geographical_Area" }, { key: "Forests", value: "Forests" }, { key: "Barren Unculturable Land", value: "Barren_Unculturable_Land" }, { key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use" }, { key: "Land Area", value: "Land_Area" }, { key: "Water Area", value: "Water_Area" }, { key: "Culturable Waste", value: "Culturable_Waste" }, { key: "Permanent Pastures", value: "Permanent_Pastures" }, { key: "Land under Tree Crops", value: "Land_under_Tree_Crops" }, { key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow" }, { key: "Current Fallow", value: "Current_Fallow" }, { key: "Total Unculturable Land", value: "Total_Unculturable_Land" }, { key: "Net Sown Area", value: "Net_Sown_Area" }, { key: "Gross Sown Area", value: "Gross_Sown_Area" }, { key: "Cropping Intensity", value: "Cropping_Intensity" },];

const obj = Comparison.reduce((acc, a) => {
  if (a.key === 'None') {
    acc.f.push(a);
  } else {
    const idx = acc.s.findIndex(b => b.key.localeCompare(a.key) > 0);
    acc.s.splice(idx === -1 ? acc.s.length : idx, 0, a);
  }
  return acc;
}, { f: [], s: [] });

const res = obj.f.concat(obj.s);

console.log(res);

答案 2 :(得分:7)

或者,您可以过滤掉所有内容,然后对其他元素进行排序。然后最后将它们重新连接在一起。

let comparison = [{key: "None", value: "None"}, {key: "Geographical Area", value: "Geographical_Area"}, {key: "Forests", value: "Forests"}, {key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}, {key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use"}, {key: "Land Area", value: "Land_Area"}, {key: "Water Area", value: "Water_Area"}, {key: "Culturable Waste", value: "Culturable_Waste"}, {key: "Permanent Pastures", value: "Permanent_Pastures"}, {key: "Land under Tree Crops", value: "Land_under_Tree_Crops"}, {key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow"}, {key: "Current Fallow", value: "Current_Fallow"}, {key: "Total Unculturable Land", value: "Total_Unculturable_Land"}, {key: "Net Sown Area", value: "Net_Sown_Area"}, {key: "Gross Sown Area", value: "Gross_Sown_Area"}, {key: "Cropping Intensity", value: "Cropping_Intensity"}];

let result = comparison
             .filter(e => e.key === 'None')
             .concat(
               comparison.filter(e => e.key !== 'None')
                         .sort((a, b) => a.key.localeCompare(b.key))
             );
               
console.log(result);

说明:

let comparison = [{key: "None", value: "None"}, {key: "Geographical Area", value: "Geographical_Area"}, {key: "Forests", value: "Forests"}, {key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}, {key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use"}, {key: "Land Area", value: "Land_Area"}, {key: "Water Area", value: "Water_Area"}, {key: "Culturable Waste", value: "Culturable_Waste"}, {key: "Permanent Pastures", value: "Permanent_Pastures"}, {key: "Land under Tree Crops", value: "Land_under_Tree_Crops"}, {key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow"}, {key: "Current Fallow", value: "Current_Fallow"}, {key: "Total Unculturable Land", value: "Total_Unculturable_Land"}, {key: "Net Sown Area", value: "Net_Sown_Area"}, {key: "Gross Sown Area", value: "Gross_Sown_Area"}, {key: "Cropping Intensity", value: "Cropping_Intensity"}];

// fetch all elements with the key 'None'
let nones = comparison.filter(e => e.key === 'None');
// fetch all elements with the key not 'None'
let others = comparison.filter(e => e.key !== 'None')
// sort the elements in the array by key
                       .sort((a, b) => a.key.localeCompare(b.key));
// concatenate the 2 arrays together
let result = nones.concat(others);

console.log(result);

Pac0s answer的贡献。编写完解决方案后,我看到我基本上做了他的解释的有效版本。我为时已晚,无法在他的回答中添加示例,因为这是目前两者中最受支持的。

答案 3 :(得分:6)

也许有更好的方法,但这应该可行:

  1. 从数组中过滤特殊值。

  2. 不使用特殊值对数组进行排序。

  3. 将特殊值重新插入数组。

有关有效的示例,请参见@Johan Wentholt's answer

答案 4 :(得分:3)

您可以使用reduce获得所需的输出:

var Comparison = [{key:"Geographical Area", value:"Geographical_Area"},   {key:"Forests", value:"Forests"},   {key:"Barren Unculturable Land", value:"Barren_Unculturable_Land"}, {key: "None", value: "None"},  {key:"Land put to Non agricultural use", value:"Land_put_to_Non_agricultural_use"}, {key:"Land Area", value:"Land_Area"},   {key:"Water Area", value:"Water_Area"}, {key:"Culturable Waste", value:"Culturable_Waste"}, {key:"Permanent Pastures", value:"Permanent_Pastures"}, {key:"Land under Tree Crops", value:"Land_under_Tree_Crops"},   {key:"Fallow Land excl Current Fallow", value:"Fallow_Land_excl_Current_Fallow"},   {key:"Current Fallow", value:"Current_Fallow"}, {key:"Total Unculturable Land", value:"Total_Unculturable_Land"},   {key:"Net Sown Area", value:"Net_Sown_Area"},   {key:"Gross Sown Area", value:"Gross_Sown_Area"},   {key:"Cropping Intensity", value:"Cropping_Intensity"},]

var Comparison_sort = Comparison
                      .sort((a, b) => a.key.localeCompare(b.key))
                      .reduce((acc, e) => {
                        e.key === 'None' ? acc.unshift(e) : acc.push(e);
                        return acc;
                      }, []);

console.log(Comparison_sort);

使用reduce版本2进行排序:

let comparison = [{key: "None", value: "None"}, {key: "Geographical Area", value: "Geographical_Area"}, {key: "Forests", value: "Forests"}, {key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}, {key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use"}, {key: "Land Area", value: "Land_Area"}, {key: "Water Area", value: "Water_Area"}, {key: "Culturable Waste", value: "Culturable_Waste"}, {key: "Permanent Pastures", value: "Permanent_Pastures"}, {key: "Land under Tree Crops", value: "Land_under_Tree_Crops"}, {key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow"}, {key: "Current Fallow", value: "Current_Fallow"}, {key: "Total Unculturable Land", value: "Total_Unculturable_Land"}, {key: "Net Sown Area", value: "Net_Sown_Area"}, {key: "Gross Sown Area", value: "Gross_Sown_Area"}, {key: "Cropping Intensity", value: "Cropping_Intensity"}];

var {Comparison_sort} = comparison.reduce((acc, obj, idx, arr) => {
                                  obj.key === 'None' ? acc['first'].push(obj) : acc['last'].push(obj)
                                  if (idx === arr.length - 1) (acc['last'].sort((a, b) => a.key.localeCompare(b.key)), acc['Comparison_sort'] = [...acc['first'], ...acc['last']])
                                  return acc
                                }, {first: [], last: [], Comparison_sort: []})

console.log(Comparison_sort);

答案 5 :(得分:2)

简单的单行代码:如果Array.prototype.sort比较功能中的任何键为“无”,则始终将其放在最上面,否则使用String.prototype.localeCompare()进行键的基本比较:

var comparison = [{key: "None", value: "None"}, {key: "Geographical Area", value: "Geographical_Area"}, {key: "Forests", value: "Forests"}, {key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}, {key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use"}, {key: "Land Area", value: "Land_Area"}, {key: "Water Area", value: "Water_Area"}, {key: "Culturable Waste", value: "Culturable_Waste"}, {key: "Permanent Pastures", value: "Permanent_Pastures"}, {key: "Land under Tree Crops", value: "Land_under_Tree_Crops"}, {key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow"}, {key: "Current Fallow", value: "Current_Fallow"}, {key: "Total Unculturable Land", value: "Total_Unculturable_Land"}, {key: "Net Sown Area", value: "Net_Sown_Area"}, {key: "Gross Sown Area", value: "Gross_Sown_Area"}, {key: "Cropping Intensity", value: "Cropping_Intensity"}];

var sorted = comparison.sort((a,b) => a.key === 'None' ? -1 : b.key === 'None' ? 1 : a.key.localeCompare(b.key));

console.log(sorted);

答案 6 :(得分:1)

只需在开头添加一张支票即可。如果它是none对象,则将其移到最前面而不执行检查。

var Comparison_sort = this.Comparison.sort(function (a, b) {
    if (a.key == "None" && a.value == "None")
        return -1;
    if (b.key == "None" && b.value == "None")
        return 1;
    if (a.key < b.key)
            return -1;
    if (a.key > b.key)
            return 1;
    return 0;
});

答案 7 :(得分:1)

<Array>.sort函数将回调作为参数。此回调将传递两个值。回调的工作是确定哪个更大。它通过返回一个数值来实现。

比方说,传递给您的回调的参数称为ab。我已经加粗了每种情况下您的回调应返回的值

  • a < b 小于0
  • a > b 大于0
  • a = b 等于0

这很容易记住,因为对于数值,您可以使用a - b获得所需的返回值。

现在,尽管传递给.sort的大多数回调很小,但 仍可以传递非常复杂的函数以满足您的需要。在这种情况下,

  • 如果a.key为None,则 a < b
  • 如果b.key为None,则 b < a
  • 否则,请使用我们当前的排序机制。

我们可以利用return语句被调用后立即退出的优势。因此,让我们逐个项目地实现此功能。

要使我们的代码超级好,让我们在两个值相等时返回“ 0”(即使这两个值的键为“ None”)

Comparison.sort(function(a, b) {
  // Our extra code
  if(a.key === b.key) return 0; // Zero (a = b)
  if(a.key === "None") return -1; // Negative (a < b)
  if(b.key === "None") return 1; // Positive (b < a)

  // Old sort
  if(a.key < b.key) return -1;
  if(b.key < a.key) return 1;  
})

解决该问题

有一些方法可以使该解决方案更短(也许更具可读性),这在代码执行简单任务时很重要。

首先要注意的是,最后一行if(b.key < a.key) return -1可以缩短为return -1;。这是因为如果使用a.key < b.keyb.key = a.key,我们会在更早的一行返回。

第二点要注意的是,使用ES6语法(可能与旧版浏览器不兼容,尤其是与Internet Explorer无关),我们可以使用箭头函数表示法进行回调。

function(a, b) {}可能会变成(a, b) => {}

要注意的第三件事是我们可以转换下面的代码块

if(a.key < b.key) return -1;
if(b.key < a.key) return 1;

进入

return (b.key < a.key) - (a.key < b.key)

这是因为在考虑减法时,true被视为1,而false被视为0true - false1 - 01false - true0 - 1-1,而0 - 00。永远不会发生true - true

答案 8 :(得分:0)

如果您希望它位于顶部 ,则可以返回-1 ,或者如果您想要将商品返回 >在列表的底部。

要从常规排序中排除的第一个或最后一个定位项不需要多个if。

this.Comparison.sort(function (a, b) {
  if(a.key == b.key) return 0;
  if (a.key == 'None' || b.key == 'None') return -1;

  if (a.key < b.key)
      return -1;
  if (a.key > b.key)
      return 1;
  return 0;
});

答案 9 :(得分:0)

const array1 = this.Comparison.filter(e => e.key === 'None');
const array2 = this.Comparison
            .filter(e => e.key !== 'None')
            .sort((a, b) => a.key.localeCompare(b.key));

this.Comparison = [].concat(array1, array2);