【问题标题】:Filter strings which doesn't includes strings from other array?过滤不包含来自其他数组的字符串的字符串?
【发布时间】:2018-09-08 17:38:53
【问题描述】:

我想通过排除包含黑名单数组中的任何子字符串的网址来过滤网址数组。

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 循环来做到这一点,但我想找到一种使用过滤器和/或减少的干净/简洁的方法。

如果我不需要遍历 x 个黑名单项目:

cleanUrls = urls.filter( url => !url.includes(blacklist[0]) )                  
                .filter( url => !url.includes(blacklist[1]) ) 

我也不想只使用 forEach 或 map 遍历黑名单,因为如果特定 url 与任何黑名单条目匹配,我想立即停止。

请使用纯 JS。谢谢你。 :)

【问题讨论】:

  • urls.some(url => blacklist.includes(url))

标签: javascript arrays string filtering


【解决方案1】:

你可以像这样使用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() 将检查特定 URL 中是否不存在 blacklist 数组的字符串。
  • .some() 将检查 blacklist 数组的任何字符串是否存在于特定 URL 中。
  • .filter() 将只选择那些将通过测试的 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'];

const cleanUrls = urls.filter(u => blacklist.every(s => !u.includes(s)));

console.log(cleanUrls);

文档:

【讨论】:

  • 我想你的意思是some 不是every
  • @HunterMcMillen 是的,我只是想some,但误写了另一个。
  • 致投反对票的人:我可以知道你投反对票的原因吗?
  • @HunterMcMillen 顺便说一句,every() 也可以,与some() 相比,它似乎更合适
【解决方案2】:

您可以使用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)

【讨论】:

    【解决方案3】:

    将黑名单 i 转换为正则表达式可能更容易:

     const block = new RegExp(blacklist.join("|"));
    

    它们很简单:

     cleanUrls = urls.filter(url => !url.match(block));
    

    【讨论】:

      【解决方案4】:

      您可以使用 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)

      【讨论】:

        【解决方案5】:

        我也不想只用 forEach 遍历黑名单 或 map 因为我想在特定 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']
        
        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));

        【讨论】:

          【解决方案6】:

          其他人已经回答了这个问题。提供两种不同的场景。

          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)

          【讨论】:

            猜你喜欢
            • 2014-07-04
            • 2020-02-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-30
            相关资源
            最近更新 更多