我想在跳过重复项的数组中添加项目。但是由于某些原因,只添加了一个项目,而没有添加第二个项目。这是我的代码。
var add = ['email1@gmail.com', 'email2@gmail.com', 'email1@gmail.com'];
var main_messages = []
var from
function findMessages(messageList) {
return messageList = from;
}
add.map(function(map){
from = map
if(main_messages.find(findMessages) === undefined){
main_messages.push(map)
}
});
console.log(main_messages)
所以预期的输出应该是
['email1@gmail.com', 'email2@gmail.com']
但是我在这段代码中得到的输出只是
['email1@gmail.com']
我做错了什么,如何解决这个问题?
答案 0 :(得分:2)
考虑以下列方式使用Array的JavaScript 1.6 / ECMAScript 5本地filter方法:
var add = ['email1@gmail.com', 'email2@gmail.com', 'email1@gmail.com'];
var main_messages = add.filter(function(v, i, a) {return a.indexOf(v) === i;});
另一个应该提供更好性能O(x)的解决方案是使用array.reduce:
main_messages = Object.keys(add.reduce(function (p,c) {return (p[c] = true,p);},{}));
两种解决方案都会产生包含以下内容的消息:
["email1@gmail.com", "email2@gmail.com"]
如果您需要支持没有实现此功能的浏览器,请务必提供Mozilla提供的pollyfill(参见页面底部)
答案 1 :(得分:2)
您在=
的退货声明中看起来错过findMessages
,因此您基本上将from
设置为messageList
而不是比较。这是固定代码
var add = ['email1@gmail.com', 'email2@gmail.com', 'email1@gmail.com'];
var main_messages = []
var from
function findMessages(messageList) {
return messageList === from;
}
add.map(function(map){
from = map
if(main_messages.find(findMessages) === undefined){
main_messages.push(map)
}
});
console.log(main_messages)
答案 2 :(得分:1)
我认为你的错误在下面的代码中
function findMessages(messageList) {
return messageList = from;
}
这里我认为你return
给它的父母,所以它显示了一个谷。
为此,您需要将messageList = from
存储在var中,然后返回该变量。
var x = messageList;
return x;
答案 3 :(得分:1)
您可以实施uniq
功能。这是filter
的专门形式。
var add = ['email1@gmail.com', 'email2@gmail.com', 'email1@gmail.com'];
var main_messages = uniq(add);
function uniq(arr) {
var result = [];
for (var i = 0; i < arr.length; i++) {
if (result.indexOf(arr[i]) === -1) {
result.push(arr[i]);
}
}
return result;
}
console.log(main_messages)
&#13;
另一方面,map
将始终返回same
大小的数组,除非你在分配任务等等。
map
将数组的每个元素传递给回调函数,用于修改单个元素而不触及实际数组。
将其视为1合1,依此类推,但您有机会更改阵列中的 ,而不是有多少 。我们的想法是,由map生成的数组具有相同的输入数组长度,但内容不同。
可以产生不同大小数组的方法,例如filter
和reduce
。
因此,你也可以做到超级简洁:
var add = ['email1@gmail.com', 'email2@gmail.com', 'email1@gmail.com'];
var main_messages = add.filter( (el, idx, input) => input.indexOf(el) === idx );
console.log(main_messages)
&#13;
答案 4 :(得分:0)
您可以使用indexOf
功能检查副本。您可以尝试以下方式将项目添加到数组中而不重复。
var add = ['email1@gmail.com', 'email2@gmail.com', 'email1@gmail.com'];
var main_messages = []
add.map(function(map){
if(main_messages.indexOf(map) == -1){
main_messages.push(map)
}
});
console.log(main_messages);
答案 5 :(得分:0)
这是一个简单的答案:https://stackoverflow.com/a/18328062/5228251
为什么这样做很难,可以使用专门针对此类操作的javascript
filter
函数更轻松地完成:
var add = ['email1@gmail.com', 'email2@gmail.com', 'email1@gmail.com'];
var main_messages = []
main_messages = add.filter( function( item, index, inputArray ) {
return inputArray.indexOf(item) == index;
});
------------------------
Output: ['email1@gmail.com', 'email2@gmail.com']
答案 6 :(得分:0)
根据您的需要,使用Set
代替数组可能就是您要找的:
Set对象允许您存储任何类型的唯一值,无论是否 原始值或对象引用。
var add = ['email1@gmail.com', 'email1@gmail.com', 'email2@gmail.com', 'email1@gmail.com'];
// Init from an iterable.
var main_messages = new Set(add);
// Add a new email (not previously in the set).
main_messages.add('email3@gmail.com');
// Try to add an existing email, does nothing.
main_messages.add('email1@gmail.com');
console.log('main_messages:')
main_messages.forEach(msg => console.log('-', msg));
&#13;
当然,只有将数据保存在Set
中,此选项才可行。在每次插入后将其转换为数组是非常低效的。
Set
是ES2015的一项功能。您可以查看compatibility table,并根据需要考虑使用polyfill。