Tengo una lista de columnas que quiero filtrar, ahora mismo estoy usando esta lógica:
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... } } Esto está funcionando bien, sin embargo, cuando tengo una matriz enorme, toma mucho tiempo, especialmente el .match ¿Cómo puedo hacerlo más rápido? ¿Usando .test o tal vez .startsWith ?
Los this.columnNames que estoy filtrando pueden tener valores como Color , Color 1 , Color 2 , etc. Es por eso que tengo la lógica:
columnName.match(c + '[ ][0-9]*$')) También puede tener valores como este: Age Range de Age Range Minimum , Age Range Maximum .
Lo que quiero es filtrar el nombre y el número, por lo que en mi código anterior Color, Color 1... pasa pero el Age Range Minimum no.
Ejemplo de entrada:
['Color', 'Color 1', 'Color 2', 'Color 3', 'Age Range', 'Age Range Minimum', 'Age Range Maximum']Salida de muestra:
['Color', 'Color 1', 'Color 2', 'Color 3']Para el caso de uso de OP, un enfoque válido fue usar una expresión regular que coincidirá con cualquier cadena que sea una secuencia de caracteres que no sean dígitos separados por espacios en blanco solamente. Algo así como ... /^(?:\D+\s+\D+)(?:\s+\D+)*$/ ... Por lo tanto, uno coincide exactamente con esas cadenas, el OP quiere rechazar. Luego, una función de filtro usa el valor de retorno negado de 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; }por cierto ... el rendimiento de expresiones regulares no es un problema en absoluto.
La siguiente prueba que filtra dos veces 70.000 entradas lo demuestra (dos veces menos de 7 mseg)...
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; }