【问题标题】:how can i match strings, if one of them are not complete equal?如果其中一个不完全相等,我该如何匹配字符串?
【发布时间】:2021-12-09 04:23:19
【问题描述】:

我有两个数组,我想验证两个数组是否同步,如果两个数组中存在相同的名称,应该存储在数组中,而其他的则没有

例如:我需要名称为 rea.jpg 的所有对象,但在我的数组中我有这样的 ['dsjajdsj...h2/rea.jpg']
这是材料

[{name: 'hgb.jpg' }, { name: 'rea.jpg'}, {  name: 'ca.png' }]

文件扩展名始终是字符串的结尾

我想验证名称数组中是否存在对象

const names = ['h2/rea.jpg']
const materials = [{
  name: 'hgb.jpg'
}, {
  name: 'rea.jpg'
}, {
  name: 'ca.png'
}]
const res = materials.filter(x => names.includes(x.name))
console.log('RES', res)

预期结果应该是[ {name: 'rea.jpg'}]

【问题讨论】:

  • 您的 names 数组具有完全限定的文件名(带路径),我假设您不想比较路径组件,只比较文件名,那么为什么不创建第二个数组只有来自names 的文件名?然后您的过滤器代码将起作用。
  • @jarmod 我怎样才能在不使用这个字符 / 的情况下创建名称列表?
  • @jarmod 我不想安装一个库或者除非它太必要?
  • @jarmod ProGu 的答案可以在所有情况下工作吗?

标签: javascript


【解决方案1】:

使用Array#some 传入自定义比较函数。

const names = ['h2/rea.jpg']
const materials = [{
  name: 'hgb.jpg'
}, {
  name: 'rea.jpg'
}, {
  name: 'ca.png'
}]
const res = materials.filter(x => names.some(y => y.endsWith('/' + x.name)))
console.log('RES', res)

【讨论】:

  • 会错误匹配law/mens-rea.jpg
  • 修改为添加前导/
  • 如果names数组元素总是包含路径,更新后的代码就OK了。
  • 原来的问题是这么说的
  • 如果名称和材料不固定,则无解。
【解决方案2】:
const names = ['h2/rea.jpg']
const materials = [{
  name: 'hgb.jpg'
}, {
  name: 'rea.jpg'
}, {
  name: 'ca.png'
}]
const res = materials.filter(x => {
    const ni = names.filter(ni => ni.includes(x.name))
    return ni.length > 0
})
console.log(res)

但是,如果名称很长并且您不想在材料的每个元素上对其进行迭代,请遵循其他建议并将名称转换为仅包含文件名。

const fnames = names.map(ni => ni.split('/')[ni.split('/').length-1])
const res = materials.filter(x => names.includes(x.name))
console.log(res)

【讨论】:

    【解决方案3】:

    在过滤器内部使用some 来实现这一点(注意,这将在 O(n^2) 中运行)。

    const names = ['h2/rea.jpg']
    const materials = [{
      name: 'hgb.jpg'
    }, {
      name: 'rea.jpg'
    }, {
      name: 'ca.png'
    }]
    const res = materials.filter(x => names.some(y => y.endsWith('/' + x.name)))
    
    console.log('RES', res)

    【讨论】:

      【解决方案4】:

      假设这是 Node.js,您可以使用 path 库将完全限定的路径名​​转换为简单的文件名,然后进行包含测试。例如:

      const path = require('path');
      
      const pathnames = ['h2/rea.jpg'];
      const filenames = pathnames.map((x) => path.basename(x));
      
      const materials = [
        {
          name: 'hgb.jpg',
        },
        {
          name: 'rea.jpg',
        },
        {
          name: 'ca.png',
        },
      ];
      
      const res = materials.filter((x) => filenames.includes(x.name));
      console.log('RES', res);
      // RES [ { name: 'rea.jpg' } ]
      

      【讨论】:

        【解决方案5】:

        如果你喜欢 oldscool,那么使用两个循环和正则表达式。

        const names = ['h2/rea.jpg']
        const materials = [{
            name: 'hgb.jpg'
          }, 
          {
            name: 'rea.jpg'
          }, 
          {
            name: 'ca.png'
          }]
        
          const res = [];
        
        materials.forEach((x) => {
            let search = x.name    
            let reg = new RegExp(search, 'g');
            let match = '';
            names.forEach((n) => {
              match = n.match(reg);
            })
            if(match) {
              res.push(x)
            }  
        })
        
        console.log('RES', res)

        【讨论】:

          猜你喜欢
          • 2020-12-25
          • 1970-01-01
          • 1970-01-01
          • 2022-12-17
          • 1970-01-01
          • 2017-12-05
          • 1970-01-01
          • 1970-01-01
          • 2021-11-22
          相关资源
          最近更新 更多