JavaScript数组排序和去重

70

我有一个 JavaScript 数组,就像这样:

var myData=['237','124','255','124','366','255'];

我需要数组元素是唯一且已排序的:

myData[0]='124';
myData[1]='237';
myData[2]='255';
myData[3]='366';

尽管数组的成员看起来像整数,但它们不是整数,因为我已经将每个成员转换为字符串:

var myData[0]=num.toString();
//...and so on.

有没有办法在JavaScript中完成所有这些任务?

19个回答

1

使用自定义排序函数的方法

//func has to return 0 in the case in which they are equal
sort_unique = function(arr,func) {
        func = func || function (a, b) {
            return a*1 - b*1;
        };
        arr = arr.sort(func);
        var ret = [arr[0]];
        for (var i = 1; i < arr.length; i++) {
            if (func(arr[i-1],arr[i]) != 0) 
                ret.push(arr[i]);
            }
        }
        return ret;
    }

例子:对于一个对象数组进行降序排列

MyArray = sort_unique(MyArray , function(a,b){
            return  b.iterator_internal*1 - a.iterator_internal*1;
        });

1
没有多余的"return"数组,没有ECMA5内置函数(我非常确定!),而且易于阅读。
function removeDuplicates(target_array) {
    target_array.sort();
    var i = 0;

    while(i < target_array.length) {
        if(target_array[i] === target_array[i+1]) {
            target_array.splice(i+1,1);
        }
        else {
            i += 1;
        }
    }
    return target_array;
}

0
我想我会发表这个答案以增加一些变化。这种去重的技巧是我大约一个月前在我目前正在进行的Flash项目中学到的。
你需要创建一个对象,并使用每个数组项填充它的键和值。由于重复的键会被丢弃,因此可以去除重复项。
var nums = [1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10];
var newNums = purgeArray(nums);

function purgeArray(ar)
{
    var obj = {};
    var temp = [];
    for(var i=0;i<ar.length;i++)
    {
        obj[ar[i]] = ar[i];
    }
    for (var item in obj)
    {
        temp.push(obj[item]);
    }
    return temp;
}

已经有其他5个答案了,所以我不认为需要发布一个排序函数。


我本来打算写一个排序函数的,但因为懒惰而在对方接受答案后放弃了。我会尽快编辑它。 - user1385191
这个函数能否扩展到对象而不是原始类型? - Juzer Ali

0
// Another way, that does not rearrange the original Array 
// and spends a little less time handling duplicates.

function uniqueSort(arr, sortby){
    var A1= arr.slice();
    A1= typeof sortby== 'function'? A1.sort(sortby): A1.sort();

    var last= A1.shift(), next, A2= [last];
    while(A1.length){
        next= A1.shift();
        while(next=== last) next= A1.shift();
        if(next!=undefined){
            A2[A2.length]= next;
            last= next;
        }
    }
    return A2;
}
var myData= ['237','124','255','124','366','255','100','1000'];
uniqueSort(myData,function(a,b){return a-b})

// the ordinary sort() returns the same array as the number sort here,
// but some strings of digits do not sort so nicely numerical.

0

O[N^2]的解决方案很糟糕,特别是当数据已经排序时,没有必要进行两个嵌套循环来删除重复项。一个循环并与前一个元素进行比较就可以很好地解决问题。

使用O[]的sort()函数的简单解决方案就足够了。我的解决方案如下:

function sortUnique(arr, compareFunction) {
  let sorted = arr.sort(compareFunction);
  let result = sorted.filter(compareFunction
    ? function(val, i, a) { return (i == 0 || compareFunction(a[i-1], val) != 0); }
    : function(val, i, a) { return (i == 0 || a[i-1] !== val); }
  );
  return result;
}

顺便说一下,可以这样做来实现Array.sortUnique()方法:

Array.prototype.sortUnique = function(compareFunction) {return sortUnique(this, compareFunction); }

此外,如果compare()函数返回0(相等元素),sort()函数可以被修改以删除第二个元素,尽管这段代码可能会变得混乱(需要在循环中修订边界)。此外,在解释性语言中,我避免编写自己的sort()函数,因为它肯定会降低性能。因此,这个补充是为了考虑ECMA 2019+。

0

var array = [2,5,4,2,5,9,4,2,6,9,0,5,4,7,8];

var unique_array = [...new Set(array)]; // [ 2, 5, 4, 9, 6, 0, 7, 8 ]

var uniqueWithSorted = unique_array.sort();

console.log(uniqueWithSorted);
output = [ 0, 2, 4, 5, 6, 7, 8, 9 ]

这里,我们只使用了Set来从数组中删除重复项,然后使用sort按升序对数组进行排序。


0

sort() 函数只有在数字具有相同的位数时才有效,例如:

var myData = ["3","11","1","2"]

将返回;

var myData = ["1","11","2","3"]

这里是mrmonkington对函数的改进

myData.sort().sort(function(a,b){return a - b;}).filter(function(el,i,a){if(i==a.indexOf(el) & el.length>0)return 1;return 0;})

上述函数还将删除空数组,您可以在下面查看演示

http://jsbin.com/ahojip/2/edit

你为什么要排序两次?& el.length > 0是什么意思? - Ry-

0

完成此任务的最快且最简单的方法。

const N = Math.pow(8, 8)
let data = Array.from({length:  N}, () => Math.floor(Math.random() * N))
let newData = {}
let len = data.length

// the magic
while (len--) {
    newData[data[len]] = true
}

-3

很抱歉,您不能将这些函数组合在一起,即您必须像这样做:

myData.unique().sort();

或者你可以实现一种类似于其他语言中可用的sortedset - 它同时具有排序和删除重复项的概念,正如你所需。

希望这可以帮助到你。

参考资料:-

Array.sort

Array.unique


1
我的Chrome不认识这个方法。 - Nakilon
3
或许你应该明确指出,你所建议的 .unique() 不是一个内置函数,它必须被定义(无论如何,在你发帖提供的链接里已经说了)。 - bufh
我同意,这会使事情变得更加实用,但也许会使事情变得太容易了吗? - Marco V

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