我希望通过排除包含黑名单数组中任何子字符串的网址来过滤网址数组。
const urls = [
'http://example.com/people/chuck',
'http://example.com/goats/sam',
'http://example.com/goats/billy',
'http://example.com/goats/linda',
'http://example.com/cows/mary',
'http://example.com/cows/betty',
'http://example.com/people/betty']
const blacklist = ['cows', 'goats']
let cleanUrls = [];
我可以使用for循环执行此操作,但我希望使用filter和/或reduce来找到一种干净/简洁的方法。
如果我不需要遍历x个黑名单项目:
cleanUrls = urls.filter( url => !url.includes(blacklist[0]) )
.filter( url => !url.includes(blacklist[1]) )
我也不想用forEach或map迭代黑名单,因为我想在特定网址与任何黑名单条目匹配时立即停止。
普通JS请。谢谢。 :)
答案 0 :(得分:4)
您可以像这样使用filter()
:
const cleanUrls = urls.filter(u => blacklist.every(s => !u.includes(s)));
或者
const cleanUrls = urls.filter(u => !blacklist.some(s => u.includes(s)));
说明强>
.includes()
将检查是否存在带有另一个字符串的子字符串。.every()
将检查特定网址中是否存在blacklist
数组的所有字符串。.some()
将检查特定网址中是否存在任何blacklist
数组字符串。.filter()
将仅选择将通过测试的网址。<强>演示:强>
const urls = [
'http://example.com/people/chuck',
'http://example.com/goats/sam',
'http://example.com/goats/billy',
'http://example.com/goats/linda',
'http://example.com/cows/mary',
'http://example.com/cows/betty',
'http://example.com/people/betty'
];
const blacklist = ['cows', 'goats'];
const cleanUrls = urls.filter(u => blacklist.every(s => !u.includes(s)));
console.log(cleanUrls);
&#13;
<强>文档:强>
答案 1 :(得分:1)
您可以使用filter()
,some()
和includes()
方法执行此操作。
const urls = ['http://example.com/people/chuck', 'http://example.com/goats/sam', 'http://example.com/goats/billy', 'http://example.com/goats/linda', 'http://example.com/cows/mary', 'http://example.com/cows/betty', 'http://example.com/people/betty'];
const blacklist = ['cows', 'goats']
const result = urls.filter(url => !blacklist.some(e => url.includes(e)))
console.log(result)
&#13;
答案 2 :(得分:0)
将黑名单i变为正则表达式可能更容易:
const block = new RegExp(blacklist.join("|"));
它简单如下:
cleanUrls = urls.filter(url => !url.match(block));
答案 3 :(得分:0)
你可以使用forEach&amp; indexOf检查第二个数组中的元素是否存在于url
中
const urls = [
'http://example.com/people/chuck',
'http://example.com/goats/sam',
'http://example.com/goats/billy',
'http://example.com/goats/linda',
'http://example.com/cows/mary',
'http://example.com/cows/betty',
'http://example.com/people/betty'
]
const blacklist = ['cows', 'goats'];
var newArray = [];
blacklist.forEach(function(item) {
if (newArray.length === 0) {
newArray = urls.filter(function(items) {
return (items.indexOf(item) === -1)
})
} else {
newArray = newArray.filter(function(items) {
return (items.indexOf(item) === -1)
})
}
});
console.log(newArray)
答案 4 :(得分:0)
我也不想用forEach迭代黑名单 或者映射因为我想在特定网址匹配时立即停止 任何黑名单条目。
该功能停止搜索是否出现黑名单中的元素。
解决此问题的递归方法:
const urls = [
'http://example.com/people/chuck',
'http://example.com/goats/sam',
'http://example.com/goats/billy',
'http://example.com/goats/linda',
'http://example.com/cows/mary',
'http://example.com/cows/betty',
'http://example.com/people/betty']
const blacklist = ['cows', 'goats']
function filter([url, ...urls] =[], blackList=[], filteredUrls =[] ){
return !url || blacklist.some(el => url.includes(el))
? filteredUrls
: filter(urls, blackList, [...filteredUrls, url])
}
console.log(filter(urls, blacklist));
&#13;
答案 5 :(得分:0)
其他人回答了这个问题。提供两种不同的场景。
const urls = [
'http://example.com/people/chuck',
'http://example.com/goats/billy',
'http://example.com/aagoatsss/billyyy',
'http://example.com/people/betty'
]
const blacklist = ['cows', 'goats']
//1st approach. It will also block 'http://example.com/aagoatsss/billyyy'
let cleanUrls1 = urls.filter(
url => blacklist.find(
blockWord => url.indexOf(blockWord) != -1 //Url contains Block Word
) === undefined //url donot contain any block word.
)
console.log(cleanUrls1)
//2nd approach. It will pass 'http://example.com/aagoatsss/billyyy'
let cleanUrls2 = urls.filter(
url => blacklist.find(
blockWord => url.split('/').indexOf(blockWord) != -1 //Url contains Block Word
) === undefined //url donot contain any block word.
)
console.log(cleanUrls2)
&#13;