JS中检查数组 - 列表是否已排序?

23

我需要创建一个程序来检查数组中的列表是否已排序。我有三个输入数据:

1,2,3,4,5

1,2,8,9,9

1,2,2,3,2

这是我的代码:

let sorts = +gets(); // 3
let list = [];

for (let i = 0; i < sorts; i++) {
    list[i] = gets().split(',').map(Number); // The Array will be: [ [ 1, 2, 3, 4, 5 ], [ 1, 2, 8, 9, 9 ], [ 1, 2, 2, 3, 2 ] ]
}

for (let i = 0; i < list[i][i].length; i++){
    if (list[i][i] < list[i][i +1]) {
        print('true');
    } else {
        print('false');
    }
}

我需要将所有列表的真假值打印到新的一行。对于此示例,我的输出应为:

true

true

false

我不知道如何解决这个问题。

9个回答

32

你可以使用array#every来检查每个值是否大于前一个值。

const isSorted = arr => arr.every((v,i,a) => !i || a[i-1] <= v);
console.log(isSorted([1,2,3,4,5]));
console.log(isSorted([1,2,8,9,9])); 
console.log(isSorted([1,2,2,3,2]));


1
让它更短:arr.every((v,i,a) => !i || a[i-1] <= v) - VisioN
@VisioN 更新了解决方案。感谢您的建议。 - Hassan Imam
使用像 !i 代替 i<1 这样的技巧真的是一个好习惯吗?否则,也许正确的做法。 - JollyJoker
2
@JollyJoker 我不会称之为技巧——它等同于 i === 0(这可能更易读)。这是该线程中最佳的解决方案,因为它将早期退出与现代功能语法结合在了一起。 - ggorlen
@ggorlen 在JavaScript中有一些标准的东西,在其他语言中被认为是要避免的奇怪之处。 - JollyJoker

28

这样怎么样:

!![1,2,3,4,5].reduce((n, item) => n !== false && item >= n && item)
// true

!![1,2,8,9,9].reduce((n, item) => n !== false && item >= n && item)
// true 

!![1,2,2,3,2].reduce((n, item) => n !== false && item >= n && item)
// false

Reduce会将数组简化成一个单一的值 - 在我们的情况下是一个布尔值。

在这里,我们每次迭代调用函数,(n,item)是我们的函数签名,它的主体是n!== false && item > -n && item - 我们确保n存在(n是我们的累加器 - 请了解一下!),测试item是否大于n,并确保item存在。

这对于数组中的每个元素都会发生。然后我们使用!!将结果强制转换为真正的布尔值。


6
虽然这很聪明,但最好给用户一个解释,没有经验的程序员可能不会理解这里发生了什么。为了测试,这里提供了一个示例:http://jsfiddle.net/briosheje/46r1jm03/。 - briosheje
6
确实。[0, 1, 2, 3, 4, 5]将返回false - VisioN
2
@VisioN 这确实是一个非常好的观点。 - Stuart
2
这会短路吗? - Bob Brinks
2
@BobBrinks 不会的。即使前两个元素没有排序,它也会继续在100万个元素的列表上运行。arr.every是我的选择。 - ggorlen
显示剩余5条评论

13
只需使用 slice 方法来尝试此方法:它将检查前一个元素是否小于下一个元素。如果对每个元素都满足该条件,则返回 true,否则返回 false。
arr.slice(1).every((item, i) => arr[i] <= item);

看看下面这个示例作为演示。

var arr = [[1,2,3,4,5],[1,2,8,9,9],[1,2,2,3,2],[0,1,2,3,4,5]];

function isArrayIsSorted (arr) {
  return arr.slice(1).every((item, i) => arr[i] <= item)
}

var result= [];
for (var i = 0; i < arr.length; i++){
result.push(isArrayIsSorted(arr[i]))
}
console.log(result);


7

排序数字列表

包括负数、零和相邻重复项

使用 every() 方法,如果所有数字按顺序排列,则返回 true,否则返回 false。以下是条件:

(num <= arr[idx + 1]) || (idx === arr.length - 1)
  1. if the current number is less than or equal to the next number...

    OR...

  2. if the current index is equal to the last index...

     return 1 (truthy)
    

演示

var arr0 = [1, 2, 3, 4, 5];
var arr1 = [1, 2, 8, 9, 9];
var arr2 = [1, 2, 2, 3, 2];
var arr3 = [0, 0, 0, 1, 3];
var arr4 = [-3, 0, 1, 3, 3];
var arr5 = [-4, -2, 0, 0, -4];

function sorted(array) {
  return array.every(function(num, idx, arr) {
    return (num <= arr[idx + 1]) || (idx === arr.length - 1) ? 1 : 0;
  });
}

console.log(arr0 +' | '+sorted(arr0));
console.log(arr1 +' | '+sorted(arr1));
console.log(arr2 +' | '+sorted(arr2));
console.log(arr3 +' | '+sorted(arr3));
console.log(arr4 +' | '+sorted(arr4));
console.log(arr5 +' | '+sorted(arr5));


请查看更新,感谢@LucaRainone。 - zer00ne
重点在于这个技巧很危险。例如,它不能处理负数[-2, 0, 3, 4, 5]。但是你的解决方案也无法处理 [0, 0, 1, 4, 5] - Luca Rainone
every 的回调函数会得到值、索引和数组。你是不是在将值与索引进行比较? - JollyJoker
请查看更新,感谢@LucaRainone - zer00ne
好注意点 @JollyJoker 所以我使用正确的参数重构了我的答案,谢谢。 - zer00ne
显示剩余2条评论

6

var str = ["1,2,3,4,5", "1,2,8,9,9", "1,2,2,3,2"];

for (var i in str){
    var list = str[i].split(',').map(Number);
    console.log(list);
    var isSorted = true;
    for(var j = 0 ; j < list.length - 1 ; j++){
        if(list[j] > list[j+1]) {
            isSorted = false;
            break;
        }
    }
    console.log(isSorted);
}


这很容易,但你知道如何创建像你的(str)一样的数组吗:https://pastebin.com/tBFd9Uft 编辑:我明白了,只需要使用gets()而不是.split()。 - Николай Матев

3

有很多方法可以实现这个目标,以下是我的方法:

const isArraySorted = array =>
  array
  .slice(0) // clone array
  .sort((a, b) => a - b) // sort it
  .every((el, i) => el === array[i]) // compare with initial value)


2
也许您可以使用这个辅助方法来检查是否正确排序:

    var arr1 = [1, 2, 3, 4, 4];
    var arr2 = [3, 2, 1];

  console.log(checkList(arr1));
  console.log(checkList(arr2));
    
    function checkList(arr) {
        for (var i = 0; i < arr.length; i++) {
            if (arr[i + 1]) {
                if (arr[i] > arr[i + 1]) {
                    return false;
                }
            }

        }
        return true;
    }


[1, 0, 1] - 真 - Dmitriy

1
你可以检查字符串化的排序后的原始数组是否与原始数组具有相同的值。可能不是最酷或最高效的方法,但我喜欢它的简单和清晰。

const arraysToCheck = [
  [1, 2, 3, 4, 5],
  [1, 2, 8, 9, 9],
  [1, 2, 2, 3, 2]
]

const isSorted = arraysToCheck.map(
  item => JSON.stringify([...item].sort((a, b) => a - b)) === JSON.stringify(item)
 );


console.log(isSorted);


-2

如果我理解你的意思,你想知道一个数组是否已经排序。这是一个解决方案的例子,请尝试一下。我在下面粘贴了一些代码。

var myArray=[1,4,3,6];

if(isSorted(myArray)){

    console.log("List is sorted");
}else{
    console.log("List is not sorted");
}

function isSorted(X){

var sorted=false;

for(var i=0;i<X.length;i++){

        var next=i+1;

    if (next<=X.length-1){

        if(X[i]>X[next]){
            sorted=false;
            break;
        }else{
            sorted=true;

        }
    }

}


return sorted;

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接