如何解决将字符串数组传递给 JavaScript indexOf()?示例:str.indexOf(arrayOfStrings)?
我需要能够检查 URL 以查看它是否包含有效流媒体服务的二级域 (SLD)。请注意,www.hulu.com 中的“hulu”是我所说的 SLD。
与其使用正则表达式解析 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”……但不是 SLD。我对此没有意见,因为我们可以控制需要验证的 URL。
解决方法
只需创建一个小辅助函数来执行您所说的操作,循环遍历数组并检查每个值。一种有效的方法是使用 Array.some,因为它会在找到真匹配后立即返回 true。
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中key是否存在:
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 写了一个更简洁的版本(如下),效果更好。特别是如果您没有被嵌套的箭头函数所迷惑!单击下面的“运行代码片段”按钮,查看 Peter 改进后的答案。
再次感谢大家的帮助!
由 Peter Seliger 编辑,以阐明一些代码行为
问:评论中的 OP ...
"...但我遇到了一些问题。所以我尝试将您的解决方案复制/粘贴到 codepen 中,但出现 TypeError: cannot read property 'includes' of undefined。..."
答:
如果我复制并粘贴到例如浏览器控制台,并调用 validateLink('https://www.hulu.com/watch/...')
它返回 false ...调用 validateLink('https://www.hoopla.com/watch/...')
返回 true。
即使函数内的 ['hoopla','kanopy',/*...*/]
是一个 sparse array(带有 empty
槽的数组,但它不是)迭代也会起作用,因为每个数组方法都会跳过 {{1} } 插槽。
用于证明上述内容的可执行代码片段...
empty
你可以尝试使用数组的 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)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。