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