Assuming I have the following:
假设我有以下几点:
var array =
[
{"name":"Joe", "age":17},
{"name":"Bob", "age":17},
{"name":"Carl", "age": 35}
]
What is the best way to be able to get an array of all of the distinct ages such that I get an result array of:
什么是最好的方法能得到所有不同年龄的数组我得到一个结果数组:
[17, 35]
Is there some way I could alternatively structure the data or better method such that I would not have to iterate through each array checking the value of "age" and check against another array for its existence, and add it if not?
是否有某种方式,我可以构造数据或更好的方法,这样我就不必遍历每个数组,检查“age”的值,并检查另一个数组是否存在,如果没有,就添加它?
If there was some way I could just pull out the distinct ages without iterating...
如果有某种方法,我可以在不重复的情况下拉出不同的年龄…
Current inefficent way I would like to improve... If it means that instead of "array" being an array of objects, but a "map" of objects with some unique key (i.e. "1,2,3") that would be okay too. Im just looking for the most performance efficient way.
目前我想改进的方法是……如果它的意思是“数组”不是一个对象数组,而是一个具有某个唯一键的对象的“映射”(即:“1、2、3”也行。我只是在寻找最高效的方法。
The following is how I currently do it, but for me, iteration appears to just be crummy for efficiency even though it does work...
下面是我目前的做法,但对我来说,迭代似乎只是为了效率,即使它确实有效……
var distinct = []
for (var i = 0; i < array.length; i++)
if (array[i].age not in distinct)
distinct.push(array[i].age)
25 个解决方案
#1
71
If this were PHP I'd build an array with the keys and take array_keys
at the end, but JS has no such luxury. Instead, try this:
如果这是PHP,我将使用键构建一个数组,并在最后使用array_keys,但是JS没有这样的奢侈。相反,试试这个:
var flags = [], output = [], l = array.length, i;
for( i=0; i<l; i++) {
if( flags[array[i].age]) continue;
flags[array[i].age] = true;
output.push(array[i].age);
}
#2
189
If you are using ES6/ES2015 or later you can do it this way:
如果你使用ES6/ ES6/ 2015或以后你可以这样做:
var unique = [...new Set(array.map(item => item.age))];
Here is an example on how to do it.
这里有一个关于如何做的例子。
EDITED based on @Jonas Kello suggestion:
编辑基于@Jonas Kello的建议:
const unique = [...new Set(array.map(item => item.age))];
#3
85
You could use a dictionary approach like this one. Basically you assign the value you want to be distinct as the key in a dictionary. If the key did not exist then you add that value as distinct.
您可以使用像这样的字典方法。基本上,你要将你想要的值指定为字典中的键。如果键不存在,那么您可以将该值添加为不同的值。
var unique = {};
var distinct = [];
for( var i in array ){
if( typeof(unique[array[i].age]) == "undefined"){
distinct.push(array[i].age);
}
unique[array[i].age] = 0;
}
Here is a working demo: http://jsfiddle.net/jbUKP/1
这里有一个工作演示:http://jsfiddle.net/jbUKP/1。
This will be O(n) where n is the number of objects in array and m is the number of unique values. There is no faster way than O(n) because you must inspect each value at least once.
这是O(n)其中n是数组中对象的个数m是唯一值的个数。没有比O(n)更快的方法,因为您必须至少检查一次每个值。
Performance
性能
http://jsperf.com/filter-versus-dictionary When I ran this dictionary was 30% faster.
当我运行这本字典时,它的速度快了30%。
#4
53
using ES6
使用ES6
let array = [
{ "name": "Joe", "age": 17 },
{ "name": "Bob", "age": 17 },
{ "name": "Carl", "age": 35 }
];
array.map(item => item.age)
.filter((value, index, self) => self.indexOf(value) === index)
> [17, 35]
#5
42
I'd just map and remove dups:
我只需要映射和删除dups:
var ages = array.map(function(obj) { return obj.age; });
ages = ages.filter(function(v,i) { return ages.indexOf(v) == i; });
console.log(ages); //=> [17, 35]
Edit: Aight! Not the most efficient way in terms of performance, but the simplest most readable IMO. If you really care about micro-optimization or you have huge amounts of data then a regular for
loop is going to be more "efficient".
编辑:Aight !这不是性能方面最有效的方法,而是最简单的最易读的IMO。如果你真的关心微优化,或者你有大量的数据,那么一个常规的循环将会变得更加“高效”。
#6
21
Using ES6 features, you could do something like:
使用ES6功能,您可以做如下事情:
const uniqueAges = [...new Set( array.map(obj => obj.age)) ];
#7
16
this is how you would solve this using new Set via ES6 for Typescript as of August 25th, 2017
这是您如何通过ES6在2017年8月25日通过ES6来解决这个问题的方法。
Array.from(new Set(yourArray.map((item: any) => item.id)))
#8
15
The forEach
version of @travis-j's answer (helpful on modern browsers and Node JS world):
@travis-j答案的forEach版本(对现代浏览器和Node JS世界有帮助):
var unique = {};
var distinct = [];
array.forEach(function (x) {
if (!unique[x.age]) {
distinct.push(x.age);
unique[x.age] = true;
}
});
34% faster on Chrome v29.0.1547: http://jsperf.com/filter-versus-dictionary/3
在Chrome v29.0.1547上速度更快:http://jsperf.com/filter-versus-dictionary/3。
And a generic solution that takes a mapper function (tad slower than direct map, but that's expected):
一个通用的解决方案,它需要一个mapper函数(tad比直接映射慢,但这是预期的):
function uniqueBy(arr, fn) {
var unique = {};
var distinct = [];
arr.forEach(function (x) {
var key = fn(x);
if (!unique[key]) {
distinct.push(key);
unique[key] = true;
}
});
return distinct;
}
// usage
uniqueBy(array, function(x){return x.age;}); // outputs [17, 35]
#9
12
I've started sticking Underscore in all new projects by default just so I never have to think about these little data-munging problems.
我已经开始在所有新项目中加入下划线,这样我就不用考虑这些小数据的问题了。
var array = [{"name":"Joe", "age":17}, {"name":"Bob", "age":17}, {"name":"Carl", "age": 35}];
console.log(_.chain(array).map(function(item) { return item.age }).uniq().value());
Produces [17, 35]
.
生产(17日35)。
#10
10
using lodash
使用lodash
var array = [
{ "name": "Joe", "age": 17 },
{ "name": "Bob", "age": 17 },
{ "name": "Carl", "age": 35 }
];
_.chain(array).pluck('age').unique().value();
> [17, 35]
#11
6
underscore.js _.uniq(_.pluck(array,"age"))
下划线。js _.uniq(_.pluck(数组,“年龄”))
#12
5
Here's another way to solve this:
这是另一种解决方法:
var result = {};
for(var i in array) {
result[array[i].age] = null;
}
result = Object.keys(result);
I have no idea how fast this solution is compared to the others, but I like the cleaner look. ;-)
我不知道这个解决方案与其他方案相比有多快,但是我喜欢干净的外观。:-)
EDIT: Okay, the above seems to be the slowest solution of all here.
编辑:好的,上面看起来是这里最慢的解决方案。
I've created a performance test case here: http://jsperf.com/distinct-values-from-array
我在这里创建了一个性能测试用例:http://jsperf.com/spect -value -from-array。
Instead of testing for the ages (Integers), I chose to compare the names (Strings).
我没有对年龄(整数)进行测试,而是选择比较它们的名称(字符串)。
Method 1 (TS's solution) is very fast. Interestingly enough, Method 7 outperforms all other solutions, here I just got rid of .indexOf() and used a "manual" implementation of it, avoiding looped function calling:
方法1 (TS的解)是非常快的。有趣的是,方法7比其他所有的解决方案都要出色,这里我只是去掉了。indexof(),并使用了它的“手动”实现,避免了循环函数调用:
var result = [];
loop1: for (var i = 0; i < array.length; i++) {
var name = array[i].name;
for (var i2 = 0; i2 < result.length; i2++) {
if (result[i2] == name) {
continue loop1;
}
}
result.push(name);
}
The difference in performance using Safari & Firefox is amazing, and it seems like Chrome does the best job on optimization.
Safari和Firefox在性能上的差异是惊人的,看起来Chrome在优化方面做得最好。
I'm not exactly sure why the above snippets is so fast compared to the others, maybe someone wiser than me has an answer. ;-)
我不太清楚为什么上面的片段比其他的都快,也许比我聪明的人有答案。:-)
#13
4
Using Lodash
使用Lodash
var array = [
{ "name": "Joe", "age": 17 },
{ "name": "Bob", "age": 17 },
{ "name": "Carl", "age": 35 }
];
_.chain(array).map('age').unique().value();
Returns [17,35]
返回(17日,35)
#14
4
function get_unique_values_from_array_object(array,property){
var unique = {};
var distinct = [];
for( var i in array ){
if( typeof(unique[array[i][property]]) == "undefined"){
distinct.push(array[i]);
}
unique[array[i][property]] = 0;
}
return distinct;
}
#15
2
Just found this and I thought it's useful
刚发现这个,我觉得它很有用。
_.map(_.indexBy(records, '_id'), function(obj){return obj})
Again using underscore, so if you have an object like this
再次使用下划线,如果你有这样的对象。
var records = [{_id:1,name:'one', _id:2,name:'two', _id:1,name:'one'}]
it will give you the unique objects only.
它只会给你唯一的对象。
What happens here is that indexBy
returns a map like this
这里发生的是,indexBy返回一个这样的映射!
{ 1:{_id:1,name:'one'}, 2:{_id:2,name:'two'} }
and just because it's a map, all keys are unique.
因为它是一张地图,所有的键都是唯一的。
Then I'm just mapping this list back to array.
然后我将这个列表映射回数组。
In case you need only the distinct values
以防您只需要不同的值。
_.map(_.indexBy(records, '_id'), function(obj,key){return key})
Keep in mind that the key
is returned as a string so, if you need integers instead, you should do
请记住,键是作为字符串返回的,因此,如果您需要整数,则应该这样做。
_.map(_.indexBy(records, '_id'), function(obj,key){return parseInt(key)})
#16
2
If like me you prefer a more "functional" without compromising speed, this example uses fast dictionary lookup wrapped inside reduce closure.
如果像我一样,您喜欢更“实用”而不影响速度,这个例子使用了快速字典查找包内减少关闭。
var array =
[
{"name":"Joe", "age":17},
{"name":"Bob", "age":17},
{"name":"Carl", "age": 35}
]
var uniqueAges = array.reduce((p,c,i,a) => {
if(!p[0][c.age]) {
p[1].push(p[0][c.age] = c.age);
}
if(i<a.length-1) {
return p
} else {
return p[1]
}
}, [{},[]])
According to this test my solution is twice as fast as the proposed answer
根据这个测试,我的解决方案是建议答案的两倍。
#17
2
i think you are looking for groupBy function (using Lodash)
我认为您是在寻找groupBy函数(使用Lodash)
_personsList = [{"name":"Joe", "age":17},
{"name":"Bob", "age":17},
{"name":"Carl", "age": 35}];
_uniqAgeList = _.groupBy(_personsList,"age");
_uniqAges = Object.keys(_uniqAgeList);
produces result:
产生的结果:
17,35
jsFiddle demo:http://jsfiddle.net/4J2SX/201/
jsFiddle演示:http://jsfiddle.net/4J2SX/201/
#18
1
If you have Array.prototype.includes or are willing to polyfill it, this works:
如果你有Array.prototype。包括或愿意多填,这是工作:
var ages = []; array.forEach(function(x) { if (!ages.includes(x.age)) ages.push(x.age); });
#19
1
Here's a versatile solution that uses reduce, allows for mapping, and maintains insertion order.
这里有一个通用的解决方案,使用reduce,允许映射,并维护插入顺序。
items: An array
项目:一个数组
mapper: A unary function that maps the item to the criteria, or empty to map the item itself.
映射器:将项目映射到标准的一元函数,或将项目本身映射为空。
function distinct(items, mapper) {
if (!mapper) mapper = (item)=>item;
return items.map(mapper).reduce((acc, item) => {
if (acc.indexOf(item) === -1) acc.push(item);
return acc;
}, []);
}
Usage
使用
const distinctLastNames = distinct(items, (item)=>item.lastName);
const distinctItems = distinct(items);
You can add this to your Array prototype and leave out the items parameter if that's your style...
你可以把它添加到你的数组原型中,如果这是你的风格的话,你可以省去这些参数。
const distinctLastNames = items.distinct( (item)=>item.lastName) ) ;
const distinctItems = items.distinct() ;
You can also use a Set instead of an Array to speed up the matching.
您还可以使用Set而不是数组来加速匹配。
function distinct(items, mapper) {
if (!mapper) mapper = (item)=>item;
return items.map(mapper).reduce((acc, item) => {
acc.add(item);
return acc;
}, new Set());
}
#20
0
my two cents on this function:
我在这个函数上的两美分:
var result = [];
for (var len = array.length, i = 0; i < len; ++i) {
var age = array[i].age;
if (result.indexOf(age) > -1) continue;
result.push(age);
}
You can see the result here (Method 8) http://jsperf.com/distinct-values-from-array/3
您可以在这里看到结果(方法8)http://jsperf.com/spect -values-from-array/3。
#21
0
Using new Ecma features are great but not all users have those available yet.
使用新的Ecma特性非常好,但是并不是所有的用户都有这些功能。
Following code will attach a new function named distinct to the Global Array object. If you are trying get distinct values of an array of objects, you can pass the name of the value to get the distinct values of that type.
下面的代码将附加一个新的函数,命名为与全局数组对象不同的函数。如果您正在尝试获取一个对象数组的不同值,您可以传递该值的名称以获得该类型的不同值。
Array.prototype.distinct = function(item){ var results = [];
for (var i = 0, l = this.length; i < l; i++)
if (!item){
if (results.indexOf(this[i]) === -1)
results.push(this[i]);
} else {
if (results.indexOf(this[i][item]) === -1)
results.push(this[i][item]);
}
return results;};
Check out my post in CodePen for a demo.
查看我在CodePen的帖子做一个演示。
#22
0
Just try
试试
var x = [] ;
for (var i = 0 ; i < array.length ; i++)
{
if(x.indexOf(array[i]['age']) == -1)
{
x.push(array[i]['age']);
}
}
console.log(x);
#23
#24
0
unique(obj, prop) {
let result = [];
let seen = new Set();
Object.keys(obj)
.forEach((key) => {
let value = obj[key];
let test = !prop
? value
: value[prop];
!seen.has(test)
&& seen.add(test)
&& result.push(value);
});
return result;
}
#25
0
this function can unique array and object
这个函数可以是唯一的数组和对象。
function oaunic(x,n=0){
if(n==0) n = "elem";
else n = "elem."+n;
var uval = [];
var unic = x.filter(function(elem, index, self){
if(uval.indexOf(eval(n)) < 0){
uval.push(eval(n));
return index == self.indexOf(elem);
}
})
return unic;
}
use that like this
使用这样的
tags_obj = [{name:"milad"},{name:"maziar"},{name:"maziar"}]
tags_arr = ["milad","maziar","maziar"]
console.log(oaunic(tags_obj,"name")) //for object
console.log(oaunic(tags_arr)) //for array
#1
71
If this were PHP I'd build an array with the keys and take array_keys
at the end, but JS has no such luxury. Instead, try this:
如果这是PHP,我将使用键构建一个数组,并在最后使用array_keys,但是JS没有这样的奢侈。相反,试试这个:
var flags = [], output = [], l = array.length, i;
for( i=0; i<l; i++) {
if( flags[array[i].age]) continue;
flags[array[i].age] = true;
output.push(array[i].age);
}
#2
189
If you are using ES6/ES2015 or later you can do it this way:
如果你使用ES6/ ES6/ 2015或以后你可以这样做:
var unique = [...new Set(array.map(item => item.age))];
Here is an example on how to do it.
这里有一个关于如何做的例子。
EDITED based on @Jonas Kello suggestion:
编辑基于@Jonas Kello的建议:
const unique = [...new Set(array.map(item => item.age))];
#3
85
You could use a dictionary approach like this one. Basically you assign the value you want to be distinct as the key in a dictionary. If the key did not exist then you add that value as distinct.
您可以使用像这样的字典方法。基本上,你要将你想要的值指定为字典中的键。如果键不存在,那么您可以将该值添加为不同的值。
var unique = {};
var distinct = [];
for( var i in array ){
if( typeof(unique[array[i].age]) == "undefined"){
distinct.push(array[i].age);
}
unique[array[i].age] = 0;
}
Here is a working demo: http://jsfiddle.net/jbUKP/1
这里有一个工作演示:http://jsfiddle.net/jbUKP/1。
This will be O(n) where n is the number of objects in array and m is the number of unique values. There is no faster way than O(n) because you must inspect each value at least once.
这是O(n)其中n是数组中对象的个数m是唯一值的个数。没有比O(n)更快的方法,因为您必须至少检查一次每个值。
Performance
性能
http://jsperf.com/filter-versus-dictionary When I ran this dictionary was 30% faster.
当我运行这本字典时,它的速度快了30%。
#4
53
using ES6
使用ES6
let array = [
{ "name": "Joe", "age": 17 },
{ "name": "Bob", "age": 17 },
{ "name": "Carl", "age": 35 }
];
array.map(item => item.age)
.filter((value, index, self) => self.indexOf(value) === index)
> [17, 35]
#5
42
I'd just map and remove dups:
我只需要映射和删除dups:
var ages = array.map(function(obj) { return obj.age; });
ages = ages.filter(function(v,i) { return ages.indexOf(v) == i; });
console.log(ages); //=> [17, 35]
Edit: Aight! Not the most efficient way in terms of performance, but the simplest most readable IMO. If you really care about micro-optimization or you have huge amounts of data then a regular for
loop is going to be more "efficient".
编辑:Aight !这不是性能方面最有效的方法,而是最简单的最易读的IMO。如果你真的关心微优化,或者你有大量的数据,那么一个常规的循环将会变得更加“高效”。
#6
21
Using ES6 features, you could do something like:
使用ES6功能,您可以做如下事情:
const uniqueAges = [...new Set( array.map(obj => obj.age)) ];
#7
16
this is how you would solve this using new Set via ES6 for Typescript as of August 25th, 2017
这是您如何通过ES6在2017年8月25日通过ES6来解决这个问题的方法。
Array.from(new Set(yourArray.map((item: any) => item.id)))
#8
15
The forEach
version of @travis-j's answer (helpful on modern browsers and Node JS world):
@travis-j答案的forEach版本(对现代浏览器和Node JS世界有帮助):
var unique = {};
var distinct = [];
array.forEach(function (x) {
if (!unique[x.age]) {
distinct.push(x.age);
unique[x.age] = true;
}
});
34% faster on Chrome v29.0.1547: http://jsperf.com/filter-versus-dictionary/3
在Chrome v29.0.1547上速度更快:http://jsperf.com/filter-versus-dictionary/3。
And a generic solution that takes a mapper function (tad slower than direct map, but that's expected):
一个通用的解决方案,它需要一个mapper函数(tad比直接映射慢,但这是预期的):
function uniqueBy(arr, fn) {
var unique = {};
var distinct = [];
arr.forEach(function (x) {
var key = fn(x);
if (!unique[key]) {
distinct.push(key);
unique[key] = true;
}
});
return distinct;
}
// usage
uniqueBy(array, function(x){return x.age;}); // outputs [17, 35]
#9
12
I've started sticking Underscore in all new projects by default just so I never have to think about these little data-munging problems.
我已经开始在所有新项目中加入下划线,这样我就不用考虑这些小数据的问题了。
var array = [{"name":"Joe", "age":17}, {"name":"Bob", "age":17}, {"name":"Carl", "age": 35}];
console.log(_.chain(array).map(function(item) { return item.age }).uniq().value());
Produces [17, 35]
.
生产(17日35)。
#10
10
using lodash
使用lodash
var array = [
{ "name": "Joe", "age": 17 },
{ "name": "Bob", "age": 17 },
{ "name": "Carl", "age": 35 }
];
_.chain(array).pluck('age').unique().value();
> [17, 35]
#11
6
underscore.js _.uniq(_.pluck(array,"age"))
下划线。js _.uniq(_.pluck(数组,“年龄”))
#12
5
Here's another way to solve this:
这是另一种解决方法:
var result = {};
for(var i in array) {
result[array[i].age] = null;
}
result = Object.keys(result);
I have no idea how fast this solution is compared to the others, but I like the cleaner look. ;-)
我不知道这个解决方案与其他方案相比有多快,但是我喜欢干净的外观。:-)
EDIT: Okay, the above seems to be the slowest solution of all here.
编辑:好的,上面看起来是这里最慢的解决方案。
I've created a performance test case here: http://jsperf.com/distinct-values-from-array
我在这里创建了一个性能测试用例:http://jsperf.com/spect -value -from-array。
Instead of testing for the ages (Integers), I chose to compare the names (Strings).
我没有对年龄(整数)进行测试,而是选择比较它们的名称(字符串)。
Method 1 (TS's solution) is very fast. Interestingly enough, Method 7 outperforms all other solutions, here I just got rid of .indexOf() and used a "manual" implementation of it, avoiding looped function calling:
方法1 (TS的解)是非常快的。有趣的是,方法7比其他所有的解决方案都要出色,这里我只是去掉了。indexof(),并使用了它的“手动”实现,避免了循环函数调用:
var result = [];
loop1: for (var i = 0; i < array.length; i++) {
var name = array[i].name;
for (var i2 = 0; i2 < result.length; i2++) {
if (result[i2] == name) {
continue loop1;
}
}
result.push(name);
}
The difference in performance using Safari & Firefox is amazing, and it seems like Chrome does the best job on optimization.
Safari和Firefox在性能上的差异是惊人的,看起来Chrome在优化方面做得最好。
I'm not exactly sure why the above snippets is so fast compared to the others, maybe someone wiser than me has an answer. ;-)
我不太清楚为什么上面的片段比其他的都快,也许比我聪明的人有答案。:-)
#13
4
Using Lodash
使用Lodash
var array = [
{ "name": "Joe", "age": 17 },
{ "name": "Bob", "age": 17 },
{ "name": "Carl", "age": 35 }
];
_.chain(array).map('age').unique().value();
Returns [17,35]
返回(17日,35)
#14
4
function get_unique_values_from_array_object(array,property){
var unique = {};
var distinct = [];
for( var i in array ){
if( typeof(unique[array[i][property]]) == "undefined"){
distinct.push(array[i]);
}
unique[array[i][property]] = 0;
}
return distinct;
}
#15
2
Just found this and I thought it's useful
刚发现这个,我觉得它很有用。
_.map(_.indexBy(records, '_id'), function(obj){return obj})
Again using underscore, so if you have an object like this
再次使用下划线,如果你有这样的对象。
var records = [{_id:1,name:'one', _id:2,name:'two', _id:1,name:'one'}]
it will give you the unique objects only.
它只会给你唯一的对象。
What happens here is that indexBy
returns a map like this
这里发生的是,indexBy返回一个这样的映射!
{ 1:{_id:1,name:'one'}, 2:{_id:2,name:'two'} }
and just because it's a map, all keys are unique.
因为它是一张地图,所有的键都是唯一的。
Then I'm just mapping this list back to array.
然后我将这个列表映射回数组。
In case you need only the distinct values
以防您只需要不同的值。
_.map(_.indexBy(records, '_id'), function(obj,key){return key})
Keep in mind that the key
is returned as a string so, if you need integers instead, you should do
请记住,键是作为字符串返回的,因此,如果您需要整数,则应该这样做。
_.map(_.indexBy(records, '_id'), function(obj,key){return parseInt(key)})
#16
2
If like me you prefer a more "functional" without compromising speed, this example uses fast dictionary lookup wrapped inside reduce closure.
如果像我一样,您喜欢更“实用”而不影响速度,这个例子使用了快速字典查找包内减少关闭。
var array =
[
{"name":"Joe", "age":17},
{"name":"Bob", "age":17},
{"name":"Carl", "age": 35}
]
var uniqueAges = array.reduce((p,c,i,a) => {
if(!p[0][c.age]) {
p[1].push(p[0][c.age] = c.age);
}
if(i<a.length-1) {
return p
} else {
return p[1]
}
}, [{},[]])
According to this test my solution is twice as fast as the proposed answer
根据这个测试,我的解决方案是建议答案的两倍。
#17
2
i think you are looking for groupBy function (using Lodash)
我认为您是在寻找groupBy函数(使用Lodash)
_personsList = [{"name":"Joe", "age":17},
{"name":"Bob", "age":17},
{"name":"Carl", "age": 35}];
_uniqAgeList = _.groupBy(_personsList,"age");
_uniqAges = Object.keys(_uniqAgeList);
produces result:
产生的结果:
17,35
jsFiddle demo:http://jsfiddle.net/4J2SX/201/
jsFiddle演示:http://jsfiddle.net/4J2SX/201/
#18
1
If you have Array.prototype.includes or are willing to polyfill it, this works:
如果你有Array.prototype。包括或愿意多填,这是工作:
var ages = []; array.forEach(function(x) { if (!ages.includes(x.age)) ages.push(x.age); });
#19
1
Here's a versatile solution that uses reduce, allows for mapping, and maintains insertion order.
这里有一个通用的解决方案,使用reduce,允许映射,并维护插入顺序。
items: An array
项目:一个数组
mapper: A unary function that maps the item to the criteria, or empty to map the item itself.
映射器:将项目映射到标准的一元函数,或将项目本身映射为空。
function distinct(items, mapper) {
if (!mapper) mapper = (item)=>item;
return items.map(mapper).reduce((acc, item) => {
if (acc.indexOf(item) === -1) acc.push(item);
return acc;
}, []);
}
Usage
使用
const distinctLastNames = distinct(items, (item)=>item.lastName);
const distinctItems = distinct(items);
You can add this to your Array prototype and leave out the items parameter if that's your style...
你可以把它添加到你的数组原型中,如果这是你的风格的话,你可以省去这些参数。
const distinctLastNames = items.distinct( (item)=>item.lastName) ) ;
const distinctItems = items.distinct() ;
You can also use a Set instead of an Array to speed up the matching.
您还可以使用Set而不是数组来加速匹配。
function distinct(items, mapper) {
if (!mapper) mapper = (item)=>item;
return items.map(mapper).reduce((acc, item) => {
acc.add(item);
return acc;
}, new Set());
}
#20
0
my two cents on this function:
我在这个函数上的两美分:
var result = [];
for (var len = array.length, i = 0; i < len; ++i) {
var age = array[i].age;
if (result.indexOf(age) > -1) continue;
result.push(age);
}
You can see the result here (Method 8) http://jsperf.com/distinct-values-from-array/3
您可以在这里看到结果(方法8)http://jsperf.com/spect -values-from-array/3。
#21
0
Using new Ecma features are great but not all users have those available yet.
使用新的Ecma特性非常好,但是并不是所有的用户都有这些功能。
Following code will attach a new function named distinct to the Global Array object. If you are trying get distinct values of an array of objects, you can pass the name of the value to get the distinct values of that type.
下面的代码将附加一个新的函数,命名为与全局数组对象不同的函数。如果您正在尝试获取一个对象数组的不同值,您可以传递该值的名称以获得该类型的不同值。
Array.prototype.distinct = function(item){ var results = [];
for (var i = 0, l = this.length; i < l; i++)
if (!item){
if (results.indexOf(this[i]) === -1)
results.push(this[i]);
} else {
if (results.indexOf(this[i][item]) === -1)
results.push(this[i][item]);
}
return results;};
Check out my post in CodePen for a demo.
查看我在CodePen的帖子做一个演示。
#22
0
Just try
试试
var x = [] ;
for (var i = 0 ; i < array.length ; i++)
{
if(x.indexOf(array[i]['age']) == -1)
{
x.push(array[i]['age']);
}
}
console.log(x);
#23
#24
0
unique(obj, prop) {
let result = [];
let seen = new Set();
Object.keys(obj)
.forEach((key) => {
let value = obj[key];
let test = !prop
? value
: value[prop];
!seen.has(test)
&& seen.add(test)
&& result.push(value);
});
return result;
}
#25
0
this function can unique array and object
这个函数可以是唯一的数组和对象。
function oaunic(x,n=0){
if(n==0) n = "elem";
else n = "elem."+n;
var uval = [];
var unic = x.filter(function(elem, index, self){
if(uval.indexOf(eval(n)) < 0){
uval.push(eval(n));
return index == self.indexOf(elem);
}
})
return unic;
}
use that like this
使用这样的
tags_obj = [{name:"milad"},{name:"maziar"},{name:"maziar"}]
tags_arr = ["milad","maziar","maziar"]
console.log(oaunic(tags_obj,"name")) //for object
console.log(oaunic(tags_arr)) //for array