Javascript数组排序和唯一

时间:2011-01-28 22:25:45

标签: javascript arrays sorting unique

我有一个像这样的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中完成所有这些任务?

18 个答案:

答案 0 :(得分:127)

这实际上非常简单。如果首先对值进行排序,则更容易找到唯一值:

function sort_unique(arr) {
  if (arr.length === 0) return arr;
  arr = arr.sort(function (a, b) { return a*1 - b*1; });
  var ret = [arr[0]];
  for (var i = 1; i < arr.length; i++) { //Start loop at 1: arr[0] can never be a duplicate
    if (arr[i-1] !== arr[i]) {
      ret.push(arr[i]);
    }
  }
  return ret;
}
console.log(sort_unique(['237','124','255','124','366','255']));
//["124", "237", "255", "366"]

答案 1 :(得分:32)

在您无法预先定义函数的情况下(例如在书签中),这可能就足够了:

myData.sort().filter(function(el,i,a){return i===a.indexOf(el)})

答案 2 :(得分:16)

function sort_unique(arr) {
    return arr.sort().filter(function(el,i,a) {
        return (i==a.indexOf(el));
    });
}

答案 3 :(得分:13)

这是使用Array.protoype.reduce()的我(更现代)方法:

[2, 1, 2, 3].reduce((a, x) => a.includes(x) ? a : [...a, x], []).sort()
// returns [1, 2, 3]

编辑:评论中指出的更高效的版本:

arr.sort().filter((x, i, a) => !i || x != a[i-1])

答案 4 :(得分:12)

现在,您只需一个代码行即可获得结果。

使用Getting Started with Redux将数组缩减为唯一的值集。 之后应用new Set方法对字符串值进行排序。

ViewStateMode="Disabled"

更新,自问题发布以来,JavaScript中引入了较新的方法。

答案 5 :(得分:8)

怎么样:

array.sort().filter(function(elem, index, arr) {
  return index == arr.length - 1 || arr[index + 1] != elem
})

这类似于@loostro的答案,但不是使用indexOf而是重复每个元素的数组以验证是第一个找到的,它只是检查下一个元素是否与当前元素不同。

答案 6 :(得分:6)

尝试使用underscore

等外部库
var f = _.compose(_.uniq, function(array) {
    return _.sortBy(array, _.identity);
});

var sortedUnique = f(array);

这取决于_.compose_.uniq_.sortBy_.identity

查看实时example

它在做什么?

我们需要一个接受数组的函数,然后返回一个已删除非唯一条目的已排序数组。这个函数需要做两件事,排序和使数组唯一。

这是一个很好的作文,所以我们组成了独特的&amp;排序功能在一起。 _.uniq可以只使用一个参数应用于数组,因此它只传递给_.compose

_.sortBy函数需要排序条件函数。它需要一个返回值的函数,数组将按该值排序。由于我们排序的值是数组中的值,我们可以传递_.identity函数。

我们现在有一个函数组合(接受一个数组并返回一个唯一的数组)和一个函数(接受一个数组并返回一个排序的数组,按其值排序)。

我们只是在数组上应用合成,并且我们有唯一排序的数组。

答案 7 :(得分:5)

对于两个以上的重复值,此函数不会失败:

function unique(arr) {
    var a = [];
    var l = arr.length;
    for(var i=0; i<l; i++) {
        for(var j=i+1; j<l; j++) {
            // If a[i] is found later in the array
            if (arr[i] === arr[j])
              j = ++i;
        }
        a.push(arr[i]);
    }
    return a;
};

答案 8 :(得分: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;
    }

示例:对象数组的desc顺序

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

答案 9 :(得分:1)

没有冗余的“返回”数组,没有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;
}

答案 10 :(得分:1)

更优雅的解决方案。

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

console.log(Array.from(new Set(myData)).sort());

我知道这个问题很老了,但也许有人会派上用场

答案 11 :(得分:0)

功能排序()仅在您的号码具有相同数字时才有用,例如:

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

答案 12 :(得分: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.

答案 13 :(得分: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个其他答案,所以我认为不需要发布排序功能。

答案 14 :(得分:0)

这是一个简单的单行班轮O(N),假设:

  • 您使用的是现代浏览器或node.js
  • 你的数组是字符串

然后

> Object.keys([{}].concat(['a', 'b', 'a']).reduce((l,r) => l[r] = l ))
[ 'a', 'b' ]

<强>解释

原始数据集,假设它来自外部函数

let data = ['a', 'b', 'a']

我们希望将一个对象添加到数组的前面

let setup = [{}].concat(data)

接下来我们要将数组减少为单个值。

在上一步中,我们将对象添加到数组中,以便在此步骤中将所有值作为键粘贴到该对象上。最终结果是一个具有唯一键集的对象。

let reduced = setup.reduce((l,r) => l[r] = l)

我们设置l[r] = l因为在javascript中,当赋值语句用作表达式时,将返回赋值表达式的值。

接下来我们想要获取该对象的键

let keys = Object.keys(setup)

原始数组的唯一值集合

['a', 'b']

答案 15 :(得分:0)

O [N ^ 2]解决方案是不好的,尤其是当数据已经排序时,无需执行两个嵌套循环即可删除重复项。一个循环并与上一个元素进行比较会很好。

使用sort [)的O []的简单解决方案就足够了。我的解决方案是:

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+的考虑。

答案 16 :(得分: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
}

答案 17 :(得分:-2)

我担心你无法将这些功能结合起来,即。你必须做这样的事情: -

myData.unique().sort();

或者,您可以实现一种sortedset(在其他语言中可用) - 它可以根据您的需要提供排序和删除重复项的概念。

希望这有帮助。

参考文献: -

  

Array.sort

     

<德尔> Array.unique