我需要能够检查URL,看看它是否包含一个有效的流媒体服务的二级域(SLD)。注意,"呼啦"在www.hulu.com中就是我所说的SLD。
而不是用regex解析URL来获得SLD,或者使用像location.hostname.split('.').pop()
这样的东西来获得SLD,我想我可以使用indexOf来代替。这种方法非常有效(至少对我来说,我意识到它至少有一个严重的限制——参见下面我的注释)。
的例子。假设我想看看https://www.hulu.com/watch/...
是不是Hulu的链接。如此:
let string = 'https://www.hulu.com/watch/...';
string.indexOf('hulu') > -1 ? true : false; // returns true
我想要能够做的是传递一个可能的字符串数组到indexOf。像这样:
let validSLDs = ['hulu','netflix']
let string1 = 'www.hulu.com/watch/...';
let string2 = 'http://www.netflix.com/watch/...';
let string3 = 'imdb.com/title/....'
string1.indexOf(validSLDs); // returns true ('hulu' is a valid SLD)
string2.indexOf(validSLDs); // returns true ('netflix' is a valid SLD)
string3.indexOf(validSLDs); // returns false ('imdb' is not a valid SLD)
但是这当然不工作,因为indexOf()
期望被传递一个字符串,而不是字符串数组。
所以有一些类似的简单,优雅(香草JS)的解决方案,我没有想到?
我能想到的下一个最简单的事情是循环遍历我的validsld数组并在每个sld上调用indexOf。也许这是最好的方法。我只是想看看有没有人有更好的办法。提前感谢!
注意:我意识到我的整个方法是一种懒惰的方法,可能会导致可能的问题。例如,使用上面的代码,https://www.amazon.com/how-cancel-hulu-subscription-membership/...
也会返回true,因为单词"hulu"存在于字符串…但不是特殊障碍。我没有意见,因为我们对需要验证的URL有一些控制。
创建一个小的辅助函数,它执行您所说的操作,循环遍历数组并检查每个值。一个有效的方法是使用Array。有些,因为一旦找到真匹配,它就会返回真。
let validSLDs = ['hulu','netflix']
let string1 = 'www.hulu.com/watch/...';
let string2 = 'http://www.netflix.com/watch/...';
let string3 = 'imdb.com/title/....'
const isURLOK = (testString) => validSLDs.some(v => testString.indexOf(v) > -1);
console.log(isURLOK(string1));
console.log(isURLOK(string2));
console.log(isURLOK(string3));
let string1 = 'www.hulu.com/watch/...';
let string2 = 'http://www.netflix.com/watch/...';
let string3 = 'imdb.com/title/....'
let unverfiedSLDs = [string1, string2, string3]
let validSLDs = ['hulu', 'netflix', 'imdb'];
let allSLDsAreValid = unverifiedSLDs.every(s => controlSLDs.includes(s))
allSLDsareValid
是一个布尔值,如果所有字符串都有效,则计算结果为true
,如果至少有一个无效字符串,则计算结果为false。
如果您想要跟踪哪些sld是有效的,哪些是无效的,请尝试使用对象:
let validatedStrings = {}
unverifiedSLDs.forEach(s => {
if (validSLDs.includes(s)) {
SLDs[s] = true;
}
})
当您需要访问SLD的有效性时,您可以在validatedStrings中检查键是否存在:
validatedStrings[string1] = true
validatedStrings[string2] = true
validatedStrings[string3] = true
validatedStrings['not-valid'] = undefined
我真的很感谢所有的建议。最后,我综合了一些建议,做了如下的事情:
let link = 'www.imdb.com/title/...';
validateLink = (link) => {
let validSLDs = ['hoopla', 'kanopy' ... ];
for(let i in validSLDs) {
if(link.includes(validSLDs[i])) {
return true;
};
};
return false;
};
这似乎工作得很好(尽管它不是防弹的,正如我在最初的说明和评论中提到的)。将IMDB链接传递给函数返回false,而传递hoopla或kanopy链接返回true。我可能会尝试重构一些……但这应该可以满足我的目的。
然后Peter Seliger写了一个更简洁的版本(下图),效果更好。特别是如果你不被嵌套的箭头函数所迷惑的话!单击"运行代码段"。按钮,查看彼得改进后的答案。
再次感谢大家的帮助!
编辑为了澄清一些代码行为
Q:OP在注释…
"…但我遇到了一些问题。所以然后我尝试复制/粘贴你的解决方案到codepen,我得到一个TypeError:无法读取属性'includes'的未定义. ...">
:
如果我做一个复制粘贴到例如浏览器控制台,并调用validateLink('https://www.hulu.com/watch/...')
它返回false…调用validateLink('https://www.hoopla.com/watch/...')
返回true。
即使函数中的['hoopla', 'kanopy', /*...*/]
是一个稀疏数组(具有empty
槽位的数组,它不是),迭代也会工作,因为每个数组方法都会跳过empty
槽位。
证明上面所说的可执行代码片段…
const validateLink = link =>
['hoopla', 'kanopy', /*...*/].some(sdl => link.includes(sdl));
console.log(
"validateLink('https://www.hulu.com/watch/...') ?",
validateLink('https://www.hulu.com/watch/...') // false
);
console.log(
"validateLink('https://www.hoopla.com/watch/...') ?",
validateLink('https://www.hoopla.com/watch/...') // true
);
您可以尝试使用数组的filter
函数:
let validSLDs = ['hulu','netflix']
let string1 = 'www.hulu.com/watch/...';
let string2 = 'http://www.netflix.com/watch/...';
let string3 = 'imdb.com/title/....'
validSLDs.filter(sld => string1.indexOf(sld) !== -1).length > 0; // returns true ('hulu' is a valid SLD)
validSLDs.filter(sld => string2.indexOf(sld) !== -1).length > 0; // returns true ('netflix' is a valid SLD)
validSLDs.filter(sld => string3.indexOf(sld) !== -1).length > 0; // returns false ('imdb' is not a valid SLD)