JavaScript数组sorting和唯一

我有这样的JavaScript数组:

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

我需要数组元素是唯一的和sorting的:

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

即使数组的成员看起来像整数 ,但它们不是整数 ,因为我已经将每个成员转换为string:

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

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

这其实很简单。 如果首先对值进行sorting,find唯一的值要容易得多:

 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"] 

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

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

这是我的(更现代的)使用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]) 

尝试使用外部库如下划线

 var f = _.compose(_.uniq, function(array) { return _.sortBy(array, _.identity); }); var sortedUnique = f(array); 

这依靠_.compose_.uniq . _.sortBy_.identity . _.uniq_.sortBy . _.identity

看到现场的例子

它在做什么?

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

这是一个很好的作品,所以我们一起组成独特的sortingfunction。 _.uniq只能用一个参数应用在数组上,所以只传递给_.compose

_.sortBy函数需要一个sorting条件函数。 它期望一个函数返回一个值,数组将按照该值进行sorting。 由于我们sorting的值是数组中的值,所以我们可以传递_.identity函数。

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

我们只是在数组上应用组合,我们有我们独特的sorting数组。

这个函数不会失败超过两个重复的值:

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

怎么样:

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

这与@loostro的答案类似,但不是使用indexOf,它将重申每个元素的数组以validation是否是第一个被发现的,它只是检查下一个元素是否与当前不同。

你现在可以在一行代码中实现结果。

使用新的Set将数组减less为唯一的一组值。 之后应用sorting方法来sortingstring值。

 var myData=['237','124','255','124','366','255'] var uniqueAndSorted = [...new Set(myData)].sort() 

自从问题出现以来,在JavaScript中引入了更新的方法。

一种使用自定义sortingfunction的方法

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

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

我想我会发布这个答案的一些变化。 这种清除重复项的技术是我在一个或多个月前正在处理的Flash项目中select的。

你所做的就是创build一个对象,并使用每个数组项来填充一个键和一个值。 由于重复键被丢弃,重复被删除。

 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个其他的答案,所以我没有看到需要发布sortingfunction。

 // 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 ab}) // the ordinary sort() returns the same array as the number sort here, // but some strings of digits do not sort so nicely numerical. 

函数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 

这里是一个简单的O(N) ,假设:

  • 你在一个现代的浏览器或在node.js
  • 你的数组是string

然后

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

说明

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

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

我们想要在数组的前面添加一个对象

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

接下来我们要将数组减less为一个单一的值。

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

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

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

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

 let keys = Object.keys(setup) 

这是原始数组的唯一值的集合

 ['a', 'b'] 

恐怕你不能把这些function,即。 你必须做这样的事情:

 myData.unique().sort(); 

或者,您可以实现一种sorting集(以其他语言提供) – 它同时包含sorting和删除重复的概念,如您所需。

希望这可以帮助。

参考文献: –

的Array.sort

Array.unique