Фильтровать массив по содержанию строки и количеству повторений с jQuery - PullRequest
0 голосов
/ 02 марта 2020

Я объясню, что нужно. Надеюсь, вы можете помочь. У меня есть массив. Во-первых, два значения - вес, который не имеет значения, затем пробел и электронная почта .

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 not just 2

Я хочу новый массив, , отфильтрованный по электронной почте, который повторяется наименьшее количество раз.

должно быть:

["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 можно было бы использовать как-нибудь, но я был бы рад за помощь.

РЕДАКТИРОВАТЬ: Пожалуйста, посмотрите на этот код

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 not just 2

function extractEmails (text) { return text.match(/([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/gi); } // Please edit the regEx to get least repeated email instead all

var get_least_repeated=extractEmails(arr.toString());

new_arr = $(arr).filter(function (str) { return arr[str].indexOf(get_least_repeated) >=0; });

console.log(new_arr);

Это кажется, работает лучше, но я не очень хорош в regEx, чтобы изменить функцию 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);

Ответы [ 2 ]

0 голосов
/ 03 марта 2020

Я бы использовал объект \ словарь для подсчета количества вхождений каждого письма без какого-либо фильтра. может быть что-то вроде этого:

    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);
  }
0 голосов
/ 03 марта 2020

Опция 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

// 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)

https://jsbin.com/milemugota/edit?js, консоль

Итерация выполняется один раз над полным массивом, а затем дважды (один раз для сбора счетчиков и один раз для сортировка) по уникальному массиву.

Вариант 2

По алгоритму 1 из https://www.sneppets.com/java/find-least-common-element-in-unsorted-array/

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)

https://jsbin.com/gitacoqipa/edit?js, консоль

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...