代码之家  ›  专栏  ›  技术社区  ›  Nilay Singh

对数组进行排序,但javascript中的一个元素除外

  •  21
  • Nilay Singh  · 技术社区  · 6 年前

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

    我的数组是:

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

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

    例如,我得到的结果是:

       {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 但是我不能用这个答案来回答我的问题。

    8 回复  |  直到 6 年前
        1
  •  16
  •   spi    6 年前
    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;
    });
    

    告诉“执行常规排序,除非键为“无”,这意味着必须先执行排序。”

        2
  •  8
  •   Peter Mortensen venu    6 年前

    不是很花哨,但是一个非常简单的方法就是移除特殊元素,对数组进行排序,然后将特殊元素插入到您想要的任何索引中。

    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);
        3
  •  7
  •   3limin4t0r    6 年前

    或者,您可以过滤掉NONE并对其他元素进行排序。然后在末尾将它们相互连接起来。

    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 . 在写下我的解决方案后,我发现我基本上是对他的解释做了一个有效的版本。我太晚了,不能在他的回答中加上我的例子,因为这是目前两人中投票最多的。

        4
  •  6
  •   Peter Mortensen venu    6 年前

    可能会有更好的方法,但这应该有效:

    1. 从数组中筛选特殊值。

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

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

    有关良好的工作示例,请参见 @Johan Wentholt's answer !

        5
  •  3
  •   BlackBeard    6 年前

    你可以使用 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);

    排序使用 减少 版本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);
        6
  •  2
  •   Leonid Pyrlia    6 年前

    一个简单的一行程序:如果 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);
        7
  •  1
  •   Aplet123    6 年前

    只需在开头添加一个支票。如果是“无”对象,则将其移到前面而不执行检查。

    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;
    });
    
        8
  •  1
  •   Max    6 年前

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

    假设传递给回调的参数被调用 a b . 我用粗体标出了您的回调应该为每种情况返回的值

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

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

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

    • 如果 a.key 没有, A & B;B
    • 如果 b.key 没有, 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.key b.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 作为 0 关于减法。 true - false 1 - 0 , false - true 0 - 1 -1 ,和 0 - 0 . 永远不会有这样的情况 true - true 发生。