【问题标题】:How to filter based on string while disregarding the number in it using javascript如何基于字符串进行过滤,同时使用javascript忽略其中的数字
【发布时间】:2021-12-27 17:28:52
【问题描述】:

我有一个要过滤的列列表,现在我正在使用这个逻辑:

for (const columnName of this.columnNames) {
   const matchingColumns = fieldsForSearch.filter(c => columnName === c || 
   columnName.match(c + '[ ][0-9]*$'));
   if (matchingColumns && matchingColumns.length > 0) {
      // do something...
   }
}

这很好,但是,当我有一个巨大的数组时,它会花费很多时间,尤其是 .match 我怎样才能让它更快?使用.test.startsWith

我过滤的this.columnNames 可以具有ColorColor 1Color 2 等值。这就是我有逻辑的原因:

columnName.match(c + '[ ][0-9]*$'))

它也可以有这样的值:Age RangeAge Range MinimumAge Range Maximum

我想要过滤名称和数字,所以在我上面的代码中颜色,颜色 1... 通过但 Age Range Minimum 没有。

示例输入:

['Color', 'Color 1', 'Color 2', 'Color 3', 'Age Range', 'Age Range Minimum', 'Age Range Maximum']

样本输出:

['Color', 'Color 1', 'Color 2', 'Color 3']

【问题讨论】:

  • @Fadi 您要过滤多少数据,您是在前端还是后端使用 nodejs 进行尝试?
  • 几千条记录,在nodejs中后端
  • 令人困惑但'(?<=Color)[ ][0-9]*$'
  • @PeterSeliger - 在重读 Q 之后,如果没有 RegExp,无论如何都无法实现目标。

标签: javascript arrays regex filter match


【解决方案1】:

对于 OP 的用例,一种有效的方法是使用正则表达式,该正则表达式将匹配任何字符串,该字符串仅是由空格分隔的非数字字符序列。类似于 ... /^(?:\D+\s+\D+)(?:\s+\D+)*$/ ... 因此,一个与那些字符串完全匹配,OP 想要拒绝。然后过滤器函数使用RegExp.prototype.test 的否定返回值...

const sampleInput = ['Color', 'Color 1', 'Color 2', 'Color 3', 'Age Range', 'Age Range Minimum', 'Age Range Maximum'];
const expectedResult = ['Color', 'Color 1', 'Color 2', 'Color 3'];

// matches any string wich is a sequence of
// whitespace separated non digit characters.
// see ... [https://regex101.com/r/6EBe7U/1/]
const regXWsSeparatedNonDigitSequence = (/^(?:\D+\s+\D+)(?:\s+\D+)*$/);

console.log(
  sampleInput, ' =>',
  sampleInput.filter(item =>
    !regXWsSeparatedNonDigitSequence.test(item)
  )
);
console.log(
  'test passed ?',
  sampleInput.filter(item =>

    !regXWsSeparatedNonDigitSequence.test(item)

  ).join(',') === expectedResult.join(',')
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

顺便说一句...正则表达式的性能根本不是问题。

过滤两次 70,000 个条目的下一个测试确实证明了这一点(两次小于 7 毫秒)...

const regXWsSeparatedNonDigitSequence = (/^(?:\D+\s+\D+)(?:\s+\D+)*$/);

let testData = new Array(10_000);
let result;

// create an array of 70_000 string entries (10_000 x 7(string item count))
testData = testData
  .fill(['Color', 'Color 1', 'Color 2', 'Color 3', 'Age Range', 'Age Range Minimum', 'Age Range Maximum'])
  .flat(1);

// test with regex reference.
console.time("70,000 regX tests (reference) :: filter duration");

result = testData.filter(item =>
  !regXWsSeparatedNonDigitSequence.test(item)
)
console.timeEnd("70,000 regX tests (reference) :: filter duration");

console.log('test passed ?.. ', (result.length === 40_000));

// test with regex literal.
console.time("70,000 regX tests (literal) :: filter duration");

result = testData.filter(item =>
  !(/^(?:\D+\s+\D+)(?:\s+\D+)*$/).test(item)
)
console.timeEnd("70,000 regX tests (literal) :: filter duration");

console.log('test passed ?.. ', (result.length === 40_000));
.as-console-wrapper { min-height: 100%!important; top: 0; }

【讨论】:

  • @Fadi ... 关于上面提供的方法,还有什么问题吗?
  • 抱歉没有收到关于此帖子的任何通知,感谢您的解决方案
猜你喜欢
  • 2014-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-10
  • 2013-07-12
  • 2017-12-10
  • 2020-06-28
  • 1970-01-01
相关资源
最近更新 更多