Javascript 使用jQuery基于字符串内容和重复计数的过滤器数组
我会解释需要什么。希望你能帮忙。 我有一个数组。首先,两个数字是无关紧要的重量,然后是空格和电子邮件 我想要一个新的数组,通过电子邮件过滤,重复次数最少 应该是:Javascript 使用jQuery基于字符串内容和重复计数的过滤器数组,javascript,jquery,arrays,filtering,Javascript,Jquery,Arrays,Filtering,我会解释需要什么。希望你能帮忙。 我有一个数组。首先,两个数字是无关紧要的重量,然后是空格和电子邮件 我想要一个新的数组,通过电子邮件过滤,重复次数最少 应该是: ["10 firstemail@email.com","15 firstemail@email.com"]; 因为firstemail@email.com在运行时仅重复2次secondemail@email.com重复3次 使用的浏览器是IE8,带有jQuery必须使用jQuery,因为native.filter不起作用 我知道这可
["10 firstemail@email.com","15 firstemail@email.com"];
因为firstemail@email.com在运行时仅重复2次secondemail@email.com重复3次
使用的浏览器是IE8,带有jQuery必须使用jQuery,因为native.filter不起作用
我知道这可能需要几个foreach/fors来完成,但我正在寻找一个优化的解决方案
例如:
new_arr = $(arr).filter(function (str) { return arr[str].indexOf("firstemail@email.com") >=0; });
如果你知道的话,这是可行的firstemail@email.com在阵列中重复次数最少,但这不是解决方案,因为我不知道哪封电子邮件重复次数最少。。也许可以用Math.min,但我很乐意得到帮助
编辑:请看一下这个代码
这似乎是最有效的,但我根本不擅长正则表达式来修改extractEmails函数,以获得当前所有邮件中重复次数最少的邮件
另一个想法是以某种方式使用jQuery.grep
编辑2:我想出了我自己的优化代码@arielb的想法,以电子邮件为键,重复计数为值的对象
最终代码
var arr = new Array(
"15 secondemail@email.com",
"10 firstemail@email.com",
"25 secondemail@email.com",
"35 secondemail@email.com",
"15 firstemail@email.com",
"12 third@email.com",
"35 secondemail@email.com"
); // huge array with many emails nut just 2
var new_emails={}; //init an object
$.each(arr,function(k,v){
var justmail=v.split(" ")[1];
if(typeof(new_emails[justmail])=='undefined') new_emails[justmail]=0;
new_emails[justmail]+=1;
});
var selectedemail=''; var eminvalue=Number.MAX_VALUE;
$.each(new_emails,function(k,v){
if(v<eminvalue) {eminvalue=v;selectedemail=k;}
});
var new_arr=$(arr).filter(function (str) { return arr[str].indexOf(selectedemail) >=0; });
console.log(new_arr);
选择1
它在整个数组上迭代一次,然后两次,一次用于收集计数,一次用于在唯一数组上排序
选择2
下面的算法1来自
我会使用object \ dictionary来计算每封电子邮件的出现次数,而不使用任何过滤器。 也许是这样的:
function check(arr){
var emails={}; //init an object
for(var i=0;i<arr.length;i++){
emails[arr[i]]=++emails[arr[i]] || 1;
}
//now we are going to check which email is the least.
var arrOccurences = [];
var minValue = arr.length;
var selectedEmail = '';
jQuery.each(emails,function(key,value){
if(value<minValue){
selectedEmail=key;
minValue = value;
}
});
console.log(selectedEmail);
}
谢谢你的回答!这是可行的,但我认为一个更简洁、更快的解决方案是:在arr实际成为数组之前——它是字符串。也许我们可以将该字符串很好地正则化,并获得最少的重复电子邮件?您可以使用extractEmailsarr.toString---函数extractEmails text{return text.match/[a-zA-Z0-9.\u-]+@[a-zA-Z0-9.\u-]+\[a-zA-Z0-9.\u-]+/gi;},这样将返回所有电子邮件。。如果只是重复一次呢?然后我会将它与前面提到的过滤函数一起使用。我想不出一个方法来实现它,只需要一个正则表达式来返回最少出现的电子邮件。同样感谢选项2。如果没有人想出正则表达式的想法或更快的方法,我想我会将您标记为解决方案,因为数组非常大,操作最少越好。与其使用正则表达式匹配已知有问题的电子邮件,为什么不匹配字符串开头的一些数字和一些空白,以便更容易匹配^\d+\s+?您也可以只使用map:arr=arr.maptext=>text.replace/^\d+\s+/,这将为您提供一个电子邮件数组。那么,剩下的部分我就用reduce了。@HereticMonkey在正则表达式上有一个很好的观点。。这只是一个例子。问题是,我相信正则表达式足够强大,可以计算重复次数,选择重复次数最少的一个,避免数组上的循环。也不要忘记IE8的限制,它不支持native.mapWell,map和reduce有多填充。我也会质疑IE8的正则表达式能力。请注意,IE8已不再受Microsoft支持,因此应该就该浏览器进行一些严肃的安全讨论…每个浏览器2个FOR和1个。。阵列很大,因此缺乏性能。无论如何,谢谢你。每个都在电子邮件字典上,它只会在唯一的电子邮件上迭代。大0仍然是ON@Svetoslav我已经删除了一个,现在整个阵列只有一个,而另一个forEach只用于唯一的电子邮件地址,所以它明显小于N。
var arr = new Array(
"15 secondemail@email.com",
"10 firstemail@email.com",
"25 secondemail@email.com",
"35 secondemail@email.com",
"15 firstemail@email.com",
"12 third@email.com",
"35 secondemail@email.com"
); // huge array with many emails nut just 2
var new_emails={}; //init an object
$.each(arr,function(k,v){
var justmail=v.split(" ")[1];
if(typeof(new_emails[justmail])=='undefined') new_emails[justmail]=0;
new_emails[justmail]+=1;
});
var selectedemail=''; var eminvalue=Number.MAX_VALUE;
$.each(new_emails,function(k,v){
if(v<eminvalue) {eminvalue=v;selectedemail=k;}
});
var new_arr=$(arr).filter(function (str) { return arr[str].indexOf(selectedemail) >=0; });
console.log(new_arr);
var arr= new Array(
"10 firstemail@email.com",
"15 secondemail@email.com",
"25 secondemail@email.com",
"35 secondemail@email.com",
"15 firstemail@email.com"); // huge array with many emails nut just 2
// Collect each unique email with its count
// and an array of each occurrence of the email
// in the original array
var emails = {};
$.each(arr, function(index, str) {
var email = str.split(' ')[1];
if (!emails[email]) {
emails[email] = {values: [], count: 0}
}
emails[email].values.push(str);
emails[email].count++;
});
var emailCounts = [];
// Create an array with unique emails and their counts
$.each(emails, function(email, data) {
emailCounts.push([email, data.count])
})
// Sort the unique emails by count
emailCounts.sort(function(a, b) {
return a[1] - b[1];
});
// First element in the sorted array is the least frequent
var leastFrequentEmail = emailCounts[0][0];
console.log(emails[leastFrequentEmail].values)
function emailPart(str) {
return str.split(' ')[1];
}
var arr = new Array(
"10 firstemail@email.com",
"15 secondemail@email.com",
"25 secondemail@email.com",
"35 secondemail@email.com",
"15 firstemail@email.com"); // huge array with many emails nut just 2
// sort by email
arr.sort(function(a, b) {
var emailA = emailPart(a);
var emailB = emailPart(b)
if (emailA > emailB) {
return 1;
} else if (emailA < emailB) {
return -1;
} else {
return 0;
}
})
var currentEmailCount = 1;
var minEmailCount = arr.length + 1;
var leastCommonEmail = emailPart(arr[0]);
for (var i = 1; i < arr.length; i++) {
if (emailPart(arr[i]) == emailPart(arr[i - 1])) {
currentEmailCount++;
} else {
if (currentEmailCount < minEmailCount) {
minEmailCount = currentEmailCount;
leastCommonEmail = emailPart(arr[i - 1])
}
currentEmailCount = 1;
}
}
if (currentEmailCount < minEmailCount) {
leastCommonEmail = emailPart(arr[arr.length - 1]);
}
console.log(leastCommonEmail)
function check(arr){
var emails={}; //init an object
for(var i=0;i<arr.length;i++){
emails[arr[i]]=++emails[arr[i]] || 1;
}
//now we are going to check which email is the least.
var arrOccurences = [];
var minValue = arr.length;
var selectedEmail = '';
jQuery.each(emails,function(key,value){
if(value<minValue){
selectedEmail=key;
minValue = value;
}
});
console.log(selectedEmail);
}