[英]Filter strings which doesn't includes strings from other array?
I want to filter an array of urls by excluding ones that contain any substrings that are in a blacklist array. 我想通过排除包含黑名单数组中任何子字符串的URL来过滤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']
let cleanUrls = [];
I can do this with for-loops but I want to find a clean/concise way using filter and/or reduce. 我可以使用for循环来做到这一点,但是我想使用filter和/或reduce来找到一种简洁的方法。
If I didn't need to loop over x number of blacklist items: 如果我不需要遍历x个黑名单项目:
cleanUrls = urls.filter( url => !url.includes(blacklist[0]) )
.filter( url => !url.includes(blacklist[1]) )
I also don't want to just iterate through the blacklist with a forEach or map because I want to immediately stop if a particular url matches any blacklist entry. 我也不想只使用forEach或map遍历黑名单,因为如果特定的网址与任何黑名单条目匹配,我想立即停止。
Plain JS please. 请使用普通的JS。 Thank you.
谢谢。 :)
:)
You can use filter()
like this: 您可以像这样使用
filter()
:
const cleanUrls = urls.filter(u => blacklist.every(s => !u.includes(s)));
Or 要么
const cleanUrls = urls.filter(u => !blacklist.some(s => u.includes(s)));
Description: 描述:
.includes()
will check the existence of a sub-string withing another string. .includes()
将检查子字符串是否与另一个字符串一起存在。 .every()
will check whether none of the strings of blacklist
array exists in a particular URL. .every()
将检查特定URL中是否不存在blacklist
数组的字符串。 .some()
will check whether any of the string of blacklist
array exists in a particular URL. .some()
将检查特定URL中是否存在blacklist
数组的任何字符串。 .filter()
will select only those URL's which will pass the test. .filter()
将仅选择将通过测试的那些URL。 Demo: 演示:
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);
Docs: 文件:
You can do this with filter()
, some()
and includes()
methods. 您可以使用
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)
It might be easuer to turn the blacklist i to a Regex: 将黑名单i转换为正则表达式可能会比较容易:
const block = new RegExp(blacklist.join("|"));
Them its as simple as: 它们非常简单:
cleanUrls = urls.filter(url => !url.match(block));
You can use forEach & indexOf to check if the element from second array is present in the url 您可以使用forEach&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)
I also don't want to just iterate through the blacklist with a forEach or map because I want to immediately stop if a particular url matches any blacklist entry.
我也不想只使用forEach或map遍历黑名单,因为如果特定的网址与任何黑名单条目匹配,我想立即停止。
The function stop searching if an element from the blacklist appears. 该功能停止搜索是否出现黑名单中的元素。
Recursive way to solve this problem: 解决此问题的递归方法:
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));
Others have answered the question. 其他人已经回答了这个问题。 Providing two different scenarios.
提供两种不同的方案。
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.