Moving text to an array - question. Easy for you master coders!
Code:
text = "Blah blah blah blah blah blah Tim \
blah blah blah Tim blah blah Tim blah blah \
blah blah blah blah blah Tim";
var myName = "Tim";
var hits = [];
for (var i = 0; i < text.length; i++){
if (text[i]== "T"){
for (var j = i; j < (myName.length + i); j++){
hits.push(text[j])
}
}
}
if (hits.length === 0){
console.log("Your name wasn't found!");
} else {
console.log(hits);
}
Hi! This is basically a small project to search the text above and to move the letters of a name to an array using for loops. I've constructed the code in a specific way pertinent to the exercise I was doing on CodeAcademy, but I just don't understand this part - (myName.length + i). I don't know why I have to put + i there, why can't I just tell the code to stop running when the letters that have been moved to the array are EQUAL to myname? I hope that makes sense.
It scans the string in the variable "text" letter by letter, and as soon as it finds a "T" (i.e. any T), it will move the T and the following two letters to a result array named "hits" ... it will do that even if the "T" is not followed by "im".
Example: text="This is Tim and Thomas and Theodore"
In the end the hits array will be ["T", "h", "i", "T", "i", "m", "T", "h", "o", "T", "h", "e"] with a length of 12. This is certainly not what you wanted
Try this instead
Code:
var hits = text.match(/Tim/g).length;
console.log(hits);
Hey dude. Thanks very much for the reply. I am aware this is not perfect code, it's just a lesson on code academy. I'm also aware it's bad code and will yield terrible results, but as it stands if it picks from those letters it will display "t" "i" "m", but I have no clue why I have to put myName.length + i to get those letters. I don't know why I can't just put myName.length, and it's confusing the hell out of me!
edit: Should I just not worry about it and move on? It's really a weight on my shoulders right now
If you go through the code step by step you will immediately see
Given:
text="My name is Tim and not Thomas"
myName = "Tim"
The outer loop with var "i" will count up without doing anything until it reaches the first "T" character, which is at position i==11 (counting starts at 0)
The inner loop with var "j" will now start at position i==11 and count up to myName.length+i-1 which is 3+11-1 = 13 (length of "Tim" plus i, minus 1 because of the <) and every character from text between position 11 and (including) position 13 will be copied into the result array "hits", so it will be ["T", "i", "m"]
Then the outer loop with var "i" will continue to count up without doing anything until it reaches the next "T" character, which is at position i==23
The inner loop with var "j" will now start at position i==23 and count up to myName.length+i-1 which is 3+23-1 = 25 (length of "Tim" plus i, minus 1 because of the <) and every character from text between position 23 and (including) position 25 will be copied into the result array "hits", so it will be ["T", "i", "m", "T", "h", "o"]
Then the outer loop with var "i" will continue to count up without doing anything until it reaches the next "T" character ... or the end of the string.
hits.length == 6, so the "else" part of the condition will be executed, outputting the full "hits" array
<script type = "text/javascript">
text = "Blah blah blah blah blah blah Tim \
blah Terry blah blah Tim blah Thomas blah Tim blah blah \
blah blah blah blah blah Tim";
var myName = "Tim";
var hits = [];
var n = "";
for (var i = 0; i < text.length; i++){
if (text.charAt(i)== "T") {
for (var j = i; j < (myName.length+i); j++) {
n += text.charAt(j);
}
if (n == myName) {
hits.push(n);
}
n = "";
}
}
if (hits.length === 0){
alert("Your name wasn't found!");
}
else {
alert(hits);
alert (hits.length);
}
</script>
myName.length + i means the next 3 characters following the current position which is index i. As devnull69 has explained.
text(i) is undefined. Use text.charAt(i) instead.
While this finds Tim but not Thomas, it will also find Timothy and Timpson so not very reliable.
The regex should read
Code:
var hits = text.match(/\bTim\b/g).length; // Tim as a whole word only - not Timothy or Timpson
alert (hits);
__________________
All the code given in this post has been tested and is intended to address the question asked.
Unless stated otherwise it is not just a demonstration.
<script type = "text/javascript">
text = "Blah blah blah blah blah blah Tim \
blah Terry blah blah Tim blah Thomas blah Tim blah blah \
blah blah blah blah blah Tim";
var myName = "Tim";
var hits = [];
var n = "";
for (var i = 0; i < text.length; i++){
if (text.charAt(i)== "T") {
for (var j = i; j < (myName.length+i); j++) {
n += text.charAt(j);
}
if (n == myName) {
hits.push(n);
}
n = "";
}
}
if (hits.length === 0){
alert("Your name wasn't found!");
}
else {
alert(hits);
alert (hits.length);
}
</script>
myName.length + i means the next 3 characters following the current position which is index i. As devnull69 has explained.
text(i) is undefined. Use text.charAt(i) instead.
While this finds Tim but not Thomas, it will also find Timothy and Timpson so not very reliable.
The regex should read
Code:
var hits = text.match(/\bTim\b/g).length; // Tim as a whole word only - not Timothy or Timpson
alert (hits);
And thanks a lot for your help too mate, but I'm not looking for better code, I just wanted to know why I had to add + i to the for! Thanks anyway!
That notation has only recently been introduced into JavaScript and so only works with some browsers. If you want it to work for all browsers you need to use charAt() instead.
FWIW, this is kind of a nonsensical way to do this, no matter how you look at it.
More sensiible, in my opinion:
Code:
var text="My name is Tim and not Thomas"
var words = text.split(/\b/g); // the \b there says "break on word boundaries"
var found = [ ];
for ( var w = 0; w < words.length; ++w )
{
var word = words[w];
if ( word.charAt(0) == "T" )
{
found.push( word );
}
}
At the end of this code, found will have two elements: "Tim" and "Thomas".
If you preferred to collect the *letters* of each:
Code:
if ( word.charAt(0) == "T" )
{
for ( var c = 0; c < word.length; ++c )
{
found.push( word.charAt(c) );
}
}
If you really do want only 3 letters per found word (why??), then:
Code:
if ( word.charAt(0) == "T" )
{
for ( var c = 0; c < word.length && c < 3; ++c )
{
found.push( word.charAt(c) );
}
}
It makes much more sense to break the string into "words". You now only have to check the first letter of each word, not every character in the string.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.