Basic exercise JS: simple text search

6

I was trying to create a search in JS to find a given name in the body of a text. However, the search returns no value at all. The logic I used is:

<script>
var text = "Xxxxx, xxxx x xxxx x xxxx xxxxxx xxxxxxx. Lucas Menezes";
var myName = "Lucas";
var hits = [];
for (var x = 0; x < text.length; x = x + 1) {
    var adiction = myName.length + x;
    if (text[x] === "L") {
        if (text[adiction] === "s") {
            for (var i = x; i < adiction; i = i + 1) {
                hits.push(text[i]);
            };
        };
    };
};
if (hits.length === 0) {
    console.log("Your name wasn't found");
    console.log(adiction);
} else {
    console.log(hits);
    console.log(adiction);
}
</script>

Can anyone help me by saying what the problem is? The array hits returns empty. If I remove the second IF it even works, however it returns an inaccurate search showing any name that starts with L and its 4 subsequent characters.

    
asked by anonymous 17.01.2017 / 19:11

4 answers

4

The problem is this line:

var adiction= myName.length + x;

Considering that the index starts from 0, in a string of size 5 you will have indexes from 0 to 4. So if you add the string size you will be trying to access index 5.

So you need to subtract 1 from your final index.

var adiction= myName.length + x - 1;
    
17.01.2017 / 19:18
9

You do not have to do this "nail" search, character by character. It's easier to use indexOf :

var text = "Xxxxx, xxxx x xxxx x xxxx xxxxxx xxxxxxx. Lucas Menezes";
var myName= "Lucas";
var position = text.indexOf(myName);
console.log(position)

You can also use regular expressions:

var text = "Xxxxx, xxxx x Lucas x xxxx xxxxxx xxxxxxx. Lucas Menezes";
var myName= "Lucas";
var re = new RegExp("(\b" + myName + "\b)", 'g')
var found = re.exec(text);
console.log(found)

Probably in real life you would use one of these, or the suggestion of Antonio Alexandre, and would hardly scan the string with each character. But I understand it's a programming exercise, as you commented on one of the answers. In this sense it is totally valid. The user dsmoreira already explained well what was the problem. I just find it strange that you want to save as a result the very text that you have searched for. It would be more useful to mount an array like this:

[12, 27, ...]

In this case, you would store the (initial) position where each occurrence was found in the largest string. This is a suggestion.

    
17.01.2017 / 19:29
3

The question is already answered, but for those of interest may follow another way to find text elements using string.search that can be adapted for different uses.

<script>

texto_original = '';

window.onload=function()
{
	texto_original = document.getElementById("texto").innerHTML;
}

function busca()
{
	// Pega o conteúdo original da div com id = texto
	texto = texto_original;
	
	// Pega o termo que se quer buscar
	var termo_busca = document.getElementById("busca").value;
	
	var termo_len = termo_busca.length;
	
	var partes = new Array();
	
	partes_i = 0;

	//enquanto está achando termo_busca
	while(texto.search(termo_busca) != -1)
	{
		
		pos_proximo = texto.search(termo_busca);
		current_position = pos_proximo + termo_len;
				
		partes[partes_i] = texto.substring(0, pos_proximo); 

		//alert("Parte " + partes_i +": " + partes[partes_i]);		

		texto = texto.substring(current_position, texto.length); 		
		
		//alert("Novo texto: " + texto);		
		
		partes_i = partes_i + 1;		


	}
	partes[partes_i] = texto;
	
		
	var glue = '<span class="destacado">' + termo_busca + '</span>';
	

	var novo_conteudo = partes.join(glue);

	
	document.getElementById("texto").innerHTML = novo_conteudo;
	
}
</script>

<style>
.destacado { background-color:yellow;}
</style>



<input type="text" id="busca" value="Lucas"> <input type="button" value="Buscar" onclick="busca()"> 

<br><br>

<div id="texto">
111 xxx xxx Lucas xxx xx222 xxxx xxxx Lucas xxxx 333x xxxx xxxx
</div>

Edited 1/27/2017 at 5:08 PM:

Here's another way to do the same thing as the above code, only using replace from javascript. The difference is that with replace, if you write less code, but do not save the chunks, then this code does not give much room for modification.

<script>

texto_original = '';

window.onload=function()
{
	texto_original = document.getElementById("texto").innerHTML;
}


function busca_replace()
{
	// Pega o conteúdo original da div com id = texto
	texto = texto_original;
	
	// Pega o termo que se quer buscar
	var termo_busca = document.getElementById("busca").value;
	
	trocar_por = '<span class="destacado">' + termo_busca + '</span>';

	// criando expressão regular com a opção g e o termo_busca pra poder passar para o replace
	var regxp = new RegExp(termo_busca,"g"); 
	
	// Referência: http://stackoverflow.com/questions/494035/how-do-you-use-a-variable-in-a-regular-expression
	
	texto = texto.replace(regxp,trocar_por);
	
	document.getElementById("texto").innerHTML = texto;
}

</script>

<style>
.destacado { background-color:yellow;}
</style>


<input type="text" id="busca" value="Lucas"> <input type="button" value="Buscar" onclick="busca_replace()"> 

<br><br>

<div id="texto">
111 xxx xxx Lucas xxx xx222 xxxx xxxx Lucas xxxx 333x xxxx xxxx
</div>
    
17.01.2017 / 21:13
0

See if it caters to you:

var myText = "xxxx XXXX xxxx xxxx Junior Nunes";
var myName = 'Junior';


if(myText.indexOf(myName) != -1) {
  var hits = myName.split('');  
  console.log(hits);
}
else {
  console.log('O nome não foi encontrado');
}

The indexOf looks for a piece of text inside the string, if it does not find it it returns -1.

If I find I get the variable myName that contains the string with the name and divide all the letters into an array with split .

I think this is a simpler way to understand ...

NOTE: If you have any questions, please let me know what you think!

Edited

This one is made with for !!

var myText = "xxxx XXXX xxxx xxxx Junior Nunes";
var myName = 'Junior';

var status = 'Não achou';

for(var i = 0; i < myText.length; i++) {
  if(myText[i] == myName[0]) {
    if(myText.substr(i, myName.length) == myName) {
      status = 'Achou';
      break;
    }
  }
}

console.log(status);
    
17.01.2017 / 19:19