我有一个像这样的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中完成所有这些任务?
答案 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)
,假设:
然后
> 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.unique 德尔>