对数组进行排序,以便空值始终位于最后

时间:2015-04-23 16:21:43

标签: javascript

我需要对一个字符串数组进行排序,但我需要它以便null始终是最后一个。例如,数组:

var arr = [a, b, null, d, null]

当按升序排序时,我需要将其排序为[a, b, d, null, null],当按降序排序时,我需要将其排序为[d, b, a, null, null]

这可能吗?我尝试了下面找到的解决方案,但这不是我需要的。

How can one compare string and numeric values (respecting negative values, with null always last)?

8 个答案:

答案 0 :(得分:61)

查看.sort()并使用自定义排序执行此操作。 实施例

~

答案 1 :(得分:33)

使用自定义比较功能来区分null值:

arr.sort(function(a, b) {
    return (a===null)-(b===null) || +(a>b)||-(a<b);
});

对于降序,只需在直接比较中交换ab

arr.sort(function(a, b) {
    return (a===null)-(b===null) || -(a>b)||+(a<b);
});

答案 2 :(得分:4)

最简单的方法是首先处理null,然后根据所需的顺序处理非空案例:

function sortnull(arr, ascending) {
  // default to ascending
  if (typeof(ascending) === "undefined")
    ascending = true;

  var multi = ascending ? 1 : -1;

  var sorter = function(a, b) {
    if (a === b)          // identical? return 0
      return 0;
    else if (a === null)  // a is null? last 
      return 1;
    else if (b === null)  // b is null? last
      return -1;
    else                  // compare, negate if descending
      return a.localeCompare(b) * multi;
  }

  return arr.sort(sorter);
}

var arr = ["a", "b", null, "d", null]

console.log(sortnull(arr));        // ascending   ["a", "b", "d", null, null]
console.log(sortnull(arr, true));  // ascending   ["a", "b", "d", null, null]
console.log(sortnull(arr, false)); // descending  ["d", "b", "a", null, null]

答案 3 :(得分:3)

升序

arr.sort((a, b) => (a != null ? a : Infinity) - (b != null ? b : Infinity))

下降

arr.sort((a, b) => (b != null ? b : -Infinity) - (a != null ? a : -Infinity))

(对于降序排列(如果数组中没有负值,我建议使用0而不是-Infinity)

答案 4 :(得分:2)

如果您需要对数字进行自然排序,或者需要Collator提供的任何选项(包括提高速度和遵守语言环境),请尝试使用基于Paul Roub解决方案的这种方法,进行一些整理。我们几乎总是使用数字排序,因此使用默认值...

如果您不是Typescript爱好者,只需剥离:type规范或从摘要中复制即可。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator

const naturalCollator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
const alphabeticCollator = new Intl.Collator(undefined, {});

function nullSort(descending: boolean = false, alphabetic: boolean = false) {
  return function (a: any, b: any): number {
    if (a === b) {
      return 0;
    }
    if (a === null) {
      return 1;
    }
    if (b === null) {
      return -1;
    }

    let ret
    if (alphabetic) {
      ret = alphabeticCollator.compare(a, b)
    } else {
      ret = naturalCollator.compare(a, b)
    }
    if (descending) {
      ret = -ret
    }
    return ret
  };
}

像这样使用它。

// numeric, ascending (default)
myList.sort(nullSort());

// alphabetic, descending
myList.sort(nullSort(true, true));

您可以修改工厂方法来使用整理程序,以提高灵活性。

function nullSort(descending: boolean = false, collator: Collator = naturalCollator)

工作摘要

const naturalCollator = new Intl.Collator(undefined, {
  numeric: true,
  sensitivity: 'base'
});
const alphabeticCollator = new Intl.Collator(undefined, {});

function nullSort(descending = false, alphabetic = false) {
  return function(a, b) {
    if (a === b) {
      return 0;
    }
    if (a === null) {
      return 1;
    }
    if (b === null) {
      return -1;
    }

    let ret
    if (alphabetic) {
      ret = alphabeticCollator.compare(a, b)
    } else {
      ret = naturalCollator.compare(a, b)
    }
    if (descending) {
      ret = -ret
    }
    return ret
  };
}

const items = [null, 10, 1, 100, null, 'hello', .1, null]

console.log(items.sort(nullSort()));

答案 5 :(得分:0)

像这样,请注意:这只会将空值推到后面

var arr = ["a", null, "b"];
var arrSor = [];
arr.forEach(function (el) {

    if (el === null) {
        arrSor.push(el);
    } else {
        arrSor.unshift(el);
    }
});

答案 6 :(得分:0)

这样做:

        var arr = [a, b, null, d, null]

        foreach ($arr as $key => $value) {
           if($value == null)
           unset($arr[$key]);
           $arr[] = $value;

        }
        // rebuild array index
        $arr = array_values($arr);

        echo '<pre>';print_r($arr);die;

答案 7 :(得分:0)

我正在使用自定义索引对对象进行排序,这对我有用。我不想更改原始数组,因此将空索引保持在原处很重要。

let sorted = [...array].sort((a, b) => {
               if (!a || !b) return 0;
               else return a.CustomIndex - b.CustomIndex;
             });