Итак, я разобрался с алгоритмом. Определите переменную - инициализируйте ее как массив и словарь для хранения данных обработанного массива.
var splitCount = [];
var domainCountDict = {};
Затем вам нужно взять массив строк (arr - параметр функции) и пройти по нему. На каждой итерации вам нужно разбивать строковый элемент на другой массив для дальнейшей его обработки.
for (var i = 0; i < arr.length; i++){
splitCount = arr[i].split(",");
...
}
Так для примера входные данные
// visits = [ "800,google.com",
// "60,mail.yahoo.com",
// "10,mobile.sports.yahoo.com",
// "40,sports.yahoo.com",
// "310,reddit.com",
// "10,stackoverflow.com",
// "2,en.wikipedia.org",
// "1,es.wikipedia.org",
// "1,mobile.sports" ]
Итерация 0 будет разбита на массив ["800", "google.com"] и назначен на Var splitCount. Затем вам потребуется доступ к splitCount, и из-за форматирования ввода вам не нужно создавать цикл for. Я создал переменную для хранения текущего счетчика сайта - который всегда будет элементом 0 из-за формата входных данных.
Я не беспокоился об очистке входных данных, потому что у меня не было времени создать функцию карты, которая превратит числовые элементы в ... ну ... числа. Я полагался на предположение, что входные данные всегда будут иметь номер в 0-м индексе - что ужасно. Не делай этого.
var curCnt = 0;
if (splitCount[0]){
curCnt = splitCount[0];
}
Этот следующий кусок логики немного повредил мой мозг, потому что мне нужно было найти способ хранить каждый компонент домена и его количество в диктовке и определить, содержат ли другие домены компоненты, которые уже существуют, и, если да, увеличить их. Давайте сделаем еще несколько массивов!
var domain = [];
var currentDom = [];
if (splitCount[1] != undefined && splitCount[1]){
domain = splitCount[1].split(".");
for (var j = domain.length - 1; j >= 0; j--){
...
}
}
Выше вы увидите, что создал Array для хранения компонентов домена с именем domain, а другой с именем currentDom для хранения компонентов, которые работают и уже работают, потому что мы хотим убедиться, что мы считаем com и google.com. , Давайте посмотрим внутрь цикла for.
for (var j = domain.length - 1; j >= 0; j--){
currentDom.unshift(domain.pop());
/*console.log("current iter: " + k + "\n"
+ "currentDom: " + currentDom.join(".") + "\n"
+ "current count: " + curCnt + "\n");*/
if (currentDom.join(".") in domainCountDict){
/*console.log("currentDom2: " + currentDom.join("."));
console.log("increment existing");*/
domainCountDict[currentDom.join(".")] += parseInt(curCnt);
}
if (!(currentDom.join(".") in domainCountDict)){
/*console.log("currentDom3: " + currentDom.join("."));
console.log("increment new");*/
domainCountDict[currentDom.join(".")] = parseInt(curCnt);
//console.log(domainCountDict);
}
}
Выше вы увидите, что я повторяю в этом цикле в обратном порядке, чтобы сначала работать с TLD, а затем с доменами / поддоменами. Я выбрал выталкивание последнего элемента из конца текущего массива и его смещение в начало нового массива currentDom. Это эффективно позволит мне поработать над частью полного FQDN, чтобы определить, было ли оно включено в словарь.
У меня есть несколько операторов if, чтобы определить, включен ли currentDom в массив. Мне пришлось использовать Array.join (), чтобы точно проверить, были ли строки текущих компонентов домена включены в словарь. Если нет, то строка currentDom будет добавлена в качестве ключа, а curCnt будет назначенным значением. Если это так, то значение будет увеличиваться. Из-за моей ленивой входной санитарии в назначении curCnt мне пришлось проанализировать их как Int, потому что JS динамические типы. Я уверен, что есть лучший способ, но мой мозг болит.
Наконец, убедитесь, что вы возвращаете созданный словарь снаружи всех этих циклов for.
Полный алгоритм ниже
// Sample output (in any order/format):
// getTotalsByDomain(counts)
// 1320 com
// 900 google.com
// 410 yahoo.com
// 60 mail.yahoo.com
// 10 mobile.sports.yahoo.com
// 50 sports.yahoo.com
// 10 stackoverflow.com
// 3 org
// 3 wikipedia.org
// 2 en.wikipedia.org
// 1 es.wikipedia.org
// 1 mobile.sports
// 1 sports
let counts = [ "900,google.com",
"60,mail.yahoo.com",
"10,mobile.sports.yahoo.com",
"40,sports.yahoo.com",
"300,yahoo.com",
"10,stackoverflow.com",
"2,en.wikipedia.org",
"1,es.wikipedia.org",
"1,mobile.sports" ];
console.log(getDomainHits(counts));
function getDomainHits(arr){
var splitCount = [];
var domainCountDict = {};
for (var i = 0; i < arr.length; i++){
splitCount = arr[i].split(",");
var curCnt = 0;
if (splitCount[0]){
curCnt = splitCount[0];
}
var domain = [];
var currentDom = [];
if (splitCount[1] != undefined && splitCount[1]){
domain = splitCount[1].split(".");
for (var j = domain.length - 1; j >= 0; j--){
currentDom.unshift(domain.pop());
/*console.log("current iter: " + k + "\n"
+ "currentDom: " + currentDom.join(".") + "\n"
+ "current count: " + curCnt + "\n");*/
if (currentDom.join(".") in domainCountDict){
/*console.log("currentDom2: " + currentDom.join("."));
console.log("increment existing");*/
domainCountDict[currentDom.join(".")] += parseInt(curCnt);
}
if (!(currentDom.join(".") in domainCountDict)){
/*console.log("currentDom3: " + currentDom.join("."));
console.log("increment new");*/
domainCountDict[currentDom.join(".")] = parseInt(curCnt);
//console.log(domainCountDict);
}
}
}
}
return domainCountDict;
}