Similar function to indexof() in Javascript

Asked

Viewed 196 times

0

Supposing I have a string:

Lorem ipsum dolor sit Amet, consectetur adipiscing Elit. Praesent eget leo consectetur, condimentum est eu, convallis dolor. Aliquam fringilla et odio a congue. Phasellus accumsan, velit in elementum porttitor, massa mi tristique velit, non molestie tellus nisl et odio. Sed id Orci mollis ex egestas semper. Cras diam Purus, Viverra a Arcu non, placerat suscipit sapien. Sed suscipit tincidunt urna, in accumsan lacus suscipit a. Suspendisse ut imperdiet urna, a ultricies ex. Vivamus eu pellentesque risus, vitae suscipit odio. Nam enim leo, auctor nec molestie non, gravida felis..."

And you want to scan this string using an array of strings to know what "matchs" you find in it, how can I do it in a more performative way than using the

indexOf()

follows example of my code:

var strErro = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent eget leo consectetur, condimentum est eu, convallis dolor. Aliquam fringilla et odio a congue. Phasellus accumsan, velit in elementum porttitor, massa mi tristique velit, non molestie tellus nisl et odio. Sed id orci mollis ex egestas semper. Cras diam purus, viverra a arcu non, placerat suscipit sapien. Sed suscipit tincidunt urna, in accumsan lacus suscipit a. Suspendisse ut imperdiet urna, a ultricies ex. Vivamus eu pellentesque risus, vitae suscipit odio. Nam enim leo, auctor nec molestie non, gravida vel felis. In pharetra dolor urna, at mattis lectus finibus in. Praesent sed facilisis diam. Pellentesque ornare luctus placerat. Aenean nisl augue, hendrerit ac metus id, fringilla tempor eros. Aliquam erat volutpat. Quisque feugiat, augue vitae cursus scelerisque, libero sem pellentesque neque, non vehicula urna urna vel justo. Curabitur fringilla finibus fringilla. Curabitur fermentum eros vel massa hendrerit euismod. Curabitur scelerisque ipsum a est egestas, accumsan elementum augue interdum. Duis ex turpis, placerat non tincidunt tincidunt, viverra at lorem. Proin sapien nisi, semper in velit quis, egestas placerat eros. Pellentesque non felis auctor massa rhoncus auctor. Aenean feugiat suscipit ex, eu porttitor neque vestibulum nec. Donec sollicitudin euismod vestibulum. Proin varius, ex ac dignissim cursus, enim ex convallis quam, vel porta ante nisl tempor dui. Pellentesque vel facilisis velit, eget pharetra velit. Nulla fermentum vel turpis vel rutrum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer mattis metus auctor, volutpat justo sed, porta ante. Donec tincidunt rhoncus urna non finibus. Pellentesque ut venenatis nisi. Praesent bibendum est id sapien consequat, a molestie tellus sollicitudin. Donec nec ligula at est lacinia finibus ac id diam. Praesent efficitur diam eu diam porttitor, quis ullamcorper justo consectetur. Suspendisse lectus enim, ornare venenatis ipsum ac, efficitur sollicitudin enim. Sed at enim tempus, vestibulum arcu et, scelerisque dui. Etiam eu malesuada eros, nec rutrum justo. Cras a odio maximus, tristique nisl at, ullamcorper nibh. Nunc quis interdum magna. Ut et eros ac ligula tristique sodales et iaculis justo. Sed aliquet nulla vitae leo scelerisque, non lacinia odio efficitur. Aliquam mauris magna, dictum nec mauris et, congue viverra ligula. Aliquam vestibulum ligula in augue venenatis viverra. Pellentesque in urna at nulla placerat consectetur a eu arcu. Fusce augue mauris, suscipit vel libero eu, vulputate iaculis nunc. Aenean condimentum neque quis urna egestas, ut feugiat ex efficitur. Morbi vitae ante erat. Fusce pretium quam vel purus maximus, ut rutrum mi volutpat. Cras pellentesque aliquam justo, ut maximus lorem consectetur sit amet. Sed nec leo sed magna scelerisque euismod at eget urna.";


var erros = "";
var found = false;
var ini;
var erro = ["erro1", "erro2", "erro3", "tempor"];

for (var i=0; i<erro.length;i++){

    ini = strErro.indexOf(erro[i]);   

    if (ini!=-1 && found){
        erros+= erro[i]+" ";
    } else if (ini!=-1) {
        erros+= erro[i]+" ";
        found=true;
    }

}

if (!found) {
    strErro;
} else {
    erros;
}
  • @Rafael Acioly Thanks for helping keep the post more organized and clean!

  • And what’s the problem? The function indexOf no longer solves your case?

  • @Andersoncarloswoss I would like to know if there is any more performative way.

  • 2

    In this reply there are 6 ways to do and a test of which it concludes that the indexOf is the fastest way (for this situation).

  • @Andersoncarloswoss In my test the "regex"* was the most performative, but I believe the gain is not so great.

  • 2

    http://jsben.ch/#/xm2BV In most tests, indexes end up being faster than traditional loops

Show 1 more comment

4 answers

5

Benchmark of the proposed functions, should more arise, I update.

Chrome Version 57.0.2987.133 (64-bit)

inserir a descrição da imagem aqui

Firefox Version 51.0 (32-bit)

inserir a descrição da imagem aqui

Opera Version 43.0.2442.1144 (64-bit)

inserir a descrição da imagem aqui

  • 3

    The q shows q if you want performance even have to make different version for each browser. And monitor if remains true.

  • 1

    The Firefox JS engine has internal optimization, the result of it is the only one that varies and is usually faster than other engines, but it is not all that it manages to "pre-optimize". This optimization usually occurs if you are in functions, now note the difference if you do so: http://jsben.ch/#/rKfMX

  • Very good, great test! Interesting how the engine of each browser implements and processes different the same commands!

4


And you want to scan this string using an array of strings to know what "matchs" you find in it, how can I do it in a more performative way than using the index()

In case the indexOf this good the way this, the only thing I would do to improve (it’s just micro-optimization) would be to save the total value and reduce one of ifs:

for (var i = 0, j = erro.length, current; i < j; i++) {

    current = erro[i];

    if (strErro.indexOf(current) !== -1) {
        erros+= current+" ";
    }
}

found = erros !== ""; //Equivale ao true

Of course saving arrays values in a variable (current) and the total of .length is only significant if the var erro is giant. The 2 ifs part didn’t make much sense, because found=true will be executed only once

An addendum

If it’s to use the .some I believe that the regex is totally dispensable:

erro.some(function(current) {
    if (strErro.indexOf(current) !== -1) {
        erros += current;
    }
});
  • The var error contains approximately 90 Strings at the moment, but it grows daily.

  • 1

    That’s what I imagine @Tiaurls, so I saved .length in j

0

It’s okay to use the indexOf, but there is a way to make code cleaner using array map

var strErro = "teste teste teste";
var erros = "";
var erro = ["erro1", "erro2", "erro3", "tempor"];

erro.map(function(value){
   if(strErro.indexOf(value) > -1){
      erros+= value+" ";
   }
});

if (erros.length > 0) {   
    erros;
} else {
    strErro;
}
  • thanks, would you have some source for me to better understand how the map array works ?

  • 1

    @Tiaurls Claro. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

  • 4

    Which makes the performance worse, which is the opposite of what you want.

  • @Bigown Pq gets worse?

  • Because it’s an abstraction, it creates an indirect. If performance is required, one should not adopt the functional style unless the language can optimize this, which is not the case with JS.

  • @Matheus Thank you for the reference. When I circled the script here, apparently it got a little slower anyway, but I found interesting the concept that was presented to me from the map.

Show 1 more comment

0

Can also be done using array.some (more information here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)

The method some will go through all the items in the array, so we can use the values as regular Expression to facilitate comparison:

var strErro = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent eget leo consectetur, condimentum est eu, convallis dolor. Aliquam fringilla et odio a congue. Phasellus accumsan, velit in elementum porttitor, massa mi tristique velit, non molestie tellus nisl et odio. Sed id orci mollis ex egestas semper. Cras diam purus, viverra a arcu non, placerat suscipit sapien. Sed suscipit tincidunt urna, in accumsan lacus suscipit a. Suspendisse ut imperdiet urna, a ultricies ex. Vivamus eu pellentesque risus, vitae suscipit odio. Nam enim leo, auctor nec molestie non, gravida vel felis. In pharetra dolor urna, at mattis lectus finibus in. Praesent sed facilisis diam. Pellentesque ornare luctus placerat. Aenean nisl augue, hendrerit ac metus id, fringilla tempor eros. Aliquam erat volutpat. Quisque feugiat, augue vitae cursus scelerisque, libero sem pellentesque neque, non vehicula urna urna vel justo. Curabitur fringilla finibus fringilla. Curabitur fermentum eros vel massa hendrerit euismod. Curabitur scelerisque ipsum a est egestas, accumsan elementum augue interdum. Duis ex turpis, placerat non tincidunt tincidunt, viverra at lorem. Proin sapien nisi, semper in velit quis, egestas placerat eros. Pellentesque non felis auctor massa rhoncus auctor. Aenean feugiat suscipit ex, eu porttitor neque vestibulum nec. Donec sollicitudin euismod vestibulum. Proin varius, ex ac dignissim cursus, enim ex convallis quam, vel porta ante nisl tempor dui. Pellentesque vel facilisis velit, eget pharetra velit. Nulla fermentum vel turpis vel rutrum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer mattis metus auctor, volutpat justo sed, porta ante. Donec tincidunt rhoncus urna non finibus. Pellentesque ut venenatis nisi. Praesent bibendum est id sapien consequat, a molestie tellus sollicitudin. Donec nec ligula at est lacinia finibus ac id diam. Praesent efficitur diam eu diam porttitor, quis ullamcorper justo consectetur. Suspendisse lectus enim, ornare venenatis ipsum ac, efficitur sollicitudin enim. Sed at enim tempus, vestibulum arcu et, scelerisque dui. Etiam eu malesuada eros, nec rutrum justo. Cras a odio maximus, tristique nisl at, ullamcorper nibh. Nunc quis interdum magna. Ut et eros ac ligula tristique sodales et iaculis justo. Sed aliquet nulla vitae leo scelerisque, non lacinia odio efficitur. Aliquam mauris magna, dictum nec mauris et, congue viverra ligula. Aliquam vestibulum ligula in augue venenatis viverra. Pellentesque in urna at nulla placerat consectetur a eu arcu. Fusce augue mauris, suscipit vel libero eu, vulputate iaculis nunc. Aenean condimentum neque quis urna egestas, ut feugiat ex efficitur. Morbi vitae ante erat. Fusce pretium quam vel purus maximus, ut rutrum mi volutpat. Cras pellentesque aliquam justo, ut maximus lorem consectetur sit amet. Sed nec leo sed magna scelerisque euismod at eget urna.";

var erros="";
// usadas barras para deixar as strings prontas para serem comparadas com regex
var regexList = [/erro1/, /erro2/, /erro3/, /tempor/];
// verifica os itens do array    
var isMatch = regexList.some(function(rx) { 
  var test = rx.test(strErro);
  if (test) {
    erros += rx.toString().replace('/','').replace('/',' ');
  }
    return; 
});


console.log('erros=' + erros)

The method some performs very fast, and comparison with regex also.
Here you can see a bechmark comparing the use of for and some and compare performance: https://jsperf.com/array-some-vs-loop

  • 2

    He came to test to see if it’s faster? It may be, but I don’t know. The fundamental requirement he wants is to be faster.

  • Thank you for sharing an alternative, but the way it was implemented before seemed quicker.

  • @Tiaurls and @bigown, I tested them both and it seemed the same thing really didn’t notice a speed difference. Looking at the link I posted, in the test the loop using some only showed faster when the quantity of items to be compared is greater.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.