将项添加到跳过重复项的数组中

时间:2016-11-10 09:48:56

标签: javascript

我想在跳过重复项的数组中添加项目。但是由于某些原因,只添加了一个项目,而没有添加第二个项目。这是我的代码。

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

我做错了什么,如何解决这个问题?

7 个答案:

答案 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;
&#13;
&#13;

另一方面,map将始终返回same大小的数组,除非你在分配任务等等。

map将数组的每个元素传递给回调函数,用于修改单个元素而不触及实际数组。

将其视为1合1,依此类推,但您有机会更改阵列中的 ,而不是有多少 。我们的想法是,由map生成的数组具有相同的输入数组长度,但内容不同。

可以产生不同大小数组的方法,例如filterreduce

因此,你也可以做到超级简洁:

&#13;
&#13;
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;
&#13;
&#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对象允许您存储任何类型的唯一值,无论是否   原始值或对象引用。

&#13;
&#13;
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;
&#13;
&#13;

当然,只有将数据保存在Set中,此选项才可行。在每次插入后将其转换为数组是非常低效的。

Set是ES2015的一项功能。您可以查看compatibility table,并根据需要考虑使用polyfill