Break string into array limiting the amount of times the break is made

Asked

Viewed 131 times

3

I know we have the split to break the string in array, but if I want to split only the first time you find a certain feature?

Example:

const vogais = "a-e-i-o-u"

const arrayVogal = vogais.split('-')

console.log(arrayVogal)

[ 'a', 'e', 'i', 'o', 'u' ]

Instead, stay like this:

[ 'a', 'e-i-o-u' ]

2 answers

5

A possible solution is you can use regex to find a desired pattern and perform a split only in this first case found pattern.

In your case, when the first - is found, perform the split on it, using the regex -(.*), that serves to make the match of the first -.

What would your code look like:

const vogais = "a-e-i-o-u"

const arrayVogal = vogais.split(/-(.*)/, 2)

console.log(arrayVogal)

Note 2 inside split. It server to limit only 2 items, because the third is an empty string. See here

Now I’m going to create a function called splitAtTheFirstMatch which server to perform the split at the desired location (element) of a given string (text) and return me a structure similar to the one you reported ([ 'a', 'e-i-o-u' ]) dynamically;

const vogais = 'a-e-i-o-u';

function splitAtTheFirstMatch(text, element) {
  const regex = new RegExp(element + '(.*)');
  
  return text.split(regex, 2);

}

// veja uns testes aqui
console.log(splitAtTheFirstMatch(vogais, '-'));
console.log(splitAtTheFirstMatch(vogais, 'e'));
console.log(splitAtTheFirstMatch(vogais, 'e-'));
console.log(splitAtTheFirstMatch(vogais, 'i-'));
console.log(splitAtTheFirstMatch(vogais, 'o-'));

The new RegExp server to dynamically pass a string inside the regex.

And now you can test for any element of the string that you want to perform the split.


OBS:

  • I’m not sure this is the best regex for the case, but it works to solve your problem.

OBS2:

  • With the help of @hkotsubo, an important detail about my regex and I find it interesting to add in the answer:

And .* works because the point corresponds to any character, and the quantifier * is "greedy" and tries to grab as many characters as possible, and so it goes to the end of the string. This is why everything that comes after the hyphen is placed in the array (without the parentheses it would not work).

  • 1

    Just to make the explanation more complete, the documentation of split says that when regex has a capture group (the parentheses), the contents of this group are also placed in the array. And .* works because the point corresponds to any character, and the quantifier * is "greedy" and tries to grab as many characters as possible, and so it goes to the end of the string. This is why everything that comes after the hyphen is placed in the array (without the parentheses it would not work)

  • 1

    Exactly. Good added! I expected you to comment on my answer, because it involves regex and I do not dominate regex very well, but I have an excerpt of code that implements ...(.*) and it was only to discover that I needed the parenthesis to break my head. I chose to use it (regex within the split) to leave the answer with as little code as possible, but to answer the question.

5

One solution is to do the split and then join the parties together according to what you want:

const vogais = "a-e-i-o-u";
const arr = vogais.split('-');
const arrayVogal = [arr[0], arr.slice(1).join('-')];
console.log(arrayVogal); // [ 'a', 'e-i-o-u' ]

I mean, I get the result of split and create another array containing 2 elements:

  • the first element resulting from split
  • the joining of the other elements: first using slice to take from the second element onwards, and then join to join them into a single string

But you can also generalize to N parts, using slice to catch the N first elements (instead of catching only the first):

// separa o texto usando o separador, e faz a separação no máximo "limite" vezes
function splitLimit(texto, separador, limite) {
    var partes = texto.split(separador);
    // pega os primeiros elementos (até o limite)
    var result = partes.slice(0, limite);
    // pega os demais (após o limite) e junta tudo em uma única string
    result.push(partes.slice(limite).join(separador));
    return result;
}

const vogais = "a-e-i-o-u";

// separa no máximo 1 vez (resultando em 2 partes)
console.log(splitLimit(vogais, '-', 1)); // [ 'a', 'e-i-o-u' ]
// separa no máximo 3 vezes (resultando em 4 partes)
console.log(splitLimit(vogais, '-', 3)); // [ 'a', 'e', 'i', 'o-u' ]


For this specific case, another alternative is to use indexOf to get the index where the first hyphen occurs, and then take the parts of the string before and after this position:

const vogais = "a-e-i-o-u";
// posição do primeiro hífen
let i = vogais.indexOf('-');
// criar array com 2 elementos
let arrayVogal = [
    vogais.slice(0, i), // do início da string até o hífen
    vogais.slice(i + 1) // tudo depois do hífen
];
console.log(arrayVogal); // [ 'a', 'e-i-o-u' ]

If you want, you can take this test and see which is the fastest alternative.


Note: I also put semicolon at the end of the lines. It may sound "fresh," and I know that Javascript "accepts" the semicolon code and "works," but it avoids some bizarre situations that can occur if you don’t use them, like that one and that one (see more about this here).

Browser other questions tagged

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