因此,我被要求创建一种算法,当给出计数和站点数组的基本输入时,它将输出对JSON对象中表示的每个TLD和Subdomain的累积访问,从而产生如下数据:
1120 com
800 google.com
310 reddit.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
2 es.wikipedia.org
1 mobile.sports
1 sports
输入类似:
// 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" ]
到目前为止,我的代码看起来像这样,我知道它是错误的,但是目前我的大脑已经融化了,我不确定如何继续。我并不一定要您为我编写算法,但是我确实想从逻辑上理解如何将其分解。
function getDomainHits(arr){
var splitCount = [];
var splitDomains = [];
var domainCountDict = {"Domains" : [],"Count" : 0};
for (var i = 0; i < arr.length; i++){
splitCount = arr[i].split(",");
splitDomains = splitCount[1].split(".");
for (var j = 0; j < splitDomains.length; j++){
if (!domainCountDict.Domain.includes(splitDomains[j])){
domainCountDict.Domain.push(splitDomains[j]);
}
}
}
console.log(domainCountDict);
}
正如您所看到的,我在这里停了下来,因为我想不出将它们分成不同的键值对的最佳方法-一个是域,另一个是计数。而且我的算法没有完全符合要求。
答案 0 :(得分:0)
所以我想出了算法。定义一个变量-将其初始化为Array,以及一个字典来存储处理后的数组数据。
var splitCount = [];
var domainCountDict = {};
然后,您需要获取字符串数组(arr-函数参数)并对其进行迭代。在每次迭代中,您都需要将字符串元素拆分为另一个Array来进一步处理它。
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];
}
下一个逻辑块对我的大脑造成了一点伤害,因为我需要找到一种方法来将每个域组件及其数量存储在dict中,并确定其他域是否包含已经存在的组件,以及是否增加这些组件。让我们做更多的数组!
var domain = [];
var currentDom = [];
if (splitCount[1] != undefined && splitCount[1]){
domain = splitCount[1].split(".");
for (var j = domain.length - 1; j >= 0; j--){
...
}
}
上面,您将看到创建了一个数组来容纳称为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;
}