Why does this .indexOf method not work on this array? - javascript

I have the following code:
var newArr = [];
function mutation(arr) {
//Makes both values lowercase
for (var i = 0; i < arr.length; i++) {
newArr.push(arr[i].toLowerCase());
}
//splits the letters of the second value into separate values.
var letters = [];
letters.push(newArr[1]);
letters = letters.toString();
letters = letters.split('');
//checks to see if there is a letter that isn't in the first value.
for (var j = 0; j < letters.length; j++) {
if (newArr[1].indexOf(letters[j]) == -1) {
return false;
}
}
return true;
}
mutation(["voodoo", "no"]);
It works on something like (["hello", "hey"]), but it doesn't work on the method above. Why does the .indexOf method not work on this array?

I dont really know what the code should do but lets check it step by step:
var newArr = [];
function mutation(arr) {
// Makes both values lowercase
// arr is now ["voodoo", "no"]
for (var i = 0; i < arr.length; i++) {
newArr.push(arr[i].toLowerCase());
}
// newArr has the same content: ["voodoo", "no"]
//splits the letters of the second value into separate values.
var letters = [];
letters.push(newArr[1]); // letters is now ["no"]
letters = letters.toString(); // letters is now "no"
letters = letters.split(''); // letters is now ["n", "o"]
//checks to see if there is a letter that isn't in the first value.
for (var j = 0; j < letters.length; j++) { // foreach ["n", "o"]
if (newArr[1].indexOf(letters[j]) == -1) { // "no".indexOf("n") and "no".indexOf("o") is always > -1
return false; // so false is never returned
}
}
return true; // true is always returned
}
mutation(["voodoo", "no"]);
I think you should change the
if (newArr[1].indexOf(letters[j]) == -1)
to
if (newArr[0].indexOf(letters[j]) == -1)
if you want to test if one letter of the second word is not included in the first word.

Related

Skip numbers that include certain number in an array

I'm trying to create a function which takes 3 parameters – start, end and bannedNumber. It should print all the numbers from start to end but skip all multiples of the banned number and any number that has a banned number in it.
Here is my code:
<script>
var arr = [];
var str = "";
var newarr = [];
var str1
function Zumbaniaa(a, b, c) {
for (var i = a; i < b; i++) {
arr.push(i);
}
for (var j = 0; j < arr.length; j++) {
if (arr[j] % c == 0) {
arr.splice(j, 1);
}
}
for (var m = 0; m < arr.length; m++) {
str = arr[m].toString();
str1=str.split("");
if (str1.indexOf(c) >=0) {
arr.splice(m, 1);
}
}
return arr
}
document.write(Zumbaniaa(1, 90, 8))
console.log(str1)
</script>
For some reason the third loop is not working. It's not filtering numbers with 8 at all.
It's simplest to just not push the banned values into the array to begin with. So check if the numbers to be pushed are a multiple of the banned digit, or contain the banned digit before you push:
function filtered_range(start, end, banned) {
let nums = [];
for (let i = start; i <= end; i++) {
if (i % banned != 0 && i.toString().indexOf(banned) == -1) nums.push(i);
}
return nums;
}
console.log(filtered_range(1, 90, 8).join(' '));
Remove this line: str1 = str.split("");. It is causing indexOf() to fail. Call str.indexOf(c) instead. Then reverse the final loop.
What is happening: indexOf() works on strings and arrays. When used on a string, the character being searched for is always parsed first to a string, because strings only contain strings. When used on an array, the character being searched for isn't parsed at all, because arrays can contain strings, numbers, etc.
var arr = [];
var str = "";
var newarr = [];
var str1
function Zumbaniaa(a, b, c) {
for (var i = a; i < b; i++) {
arr.push(i);
}
for (var j = 0; j < arr.length; j++) {
if (arr[j] % c == 0) {
arr.splice(j, 1);
}
}
for (var m = arr.length - 1; m > 0; m--) {
str = arr[m].toString();
//str1 = str.split("");
if (str.indexOf(c) >= 0) {
arr.splice(m, 1);
}
}
return arr
}
Zumbaniaa(1, 90, 8);
console.log(arr);

JavaScript - Find a word string out of strings in a two dimensional array

I am trying to find a word from consecutive strings inside a two dimensional array.
For example:
array = [[0,'r',0,0,0,0,0],
[0,'a',0,0,0,0,0],
[0,'p',0,0,0,0,0],
[0,'p',0,0,0,0,0],
[0,'l',0,0,0,0,0],
[0,'e',0,0,0,0,0]];
I want to make a function that will return true if the word 'apple' is inside this array vertically. Strings need to be consecutive.
Or:
array1 = [[0,'e',0,0,0,0,0],
[0,'l',0,0,0,0,0],
[0,'p',0,0,0,0,0],
[0,'p',0,0,0,0,0],
[0,'a',0,0,0,0,0],
[0,'q',0,0,0,0,0]];
It should work from top to bottom and from bottom to top.
This should return false since there are no consecutive letters:
array2 = [[0,'e',0,0,0,0,0],
[0,'p',0,0,0,0,0],
[0,'l',0,0,0,0,0],
[0,'p',0,0,0,0,0],
[0,'a',0,0,0,0,0],
[0,'q',0,0,0,0,0]];
Can you help please?
Here's a function that does exactly what you need:
let array1 = [
[0,'r',0,0,0,0,0],
[0,'a',0,0,0,0,0],
[0,'p',0,0,0,0,0],
[0,'p',0,0,0,0,0],
[0,'l',0,0,0,0,0],
[0,'e',0,0,0,0,0]
];
let array2 = [
[0,'r',0,0,0,0,0],
[0,'e',0,0,0,0,0],
[0,'l',0,0,0,0,0],
[0,'p',0,0,0,0,0],
[0,'p',0,0,0,0,0],
[0,'a',0,0,0,0,0]
];
function includesWordVertically(matrix, word) {
for (let j = 0 ; j < matrix[0].length ; j++) {
let verticalWord = '';
for (let i = 0 ; i < matrix.length ; i++) {
verticalWord += matrix[i][j];
}
if ((verticalWord.includes(word)) ||
(verticalWord.split('').reverse().join('').includes(word)))
{
return true;
}
}
return false;
}
console.log(includesWordVertically(array1, 'apple'));
// true
console.log(includesWordVertically(array2, 'apple'));
// true
Note that this function does not do the necessary checks (e.g. matrix not empty, all rows have the same length, etc).
I would combine a single string from all characters in one vertical column, and also add another set of same characters, so if the word Apple is divided, you will fins it is a string. After adding all characters twice, you will get a string like 'leappleapp' and you will find an apple there
Returns true Only if found in a straight column.
var array1 = [[0,'a',0,0,0,0,0],
[0,'p',0,0,0,0,0],
[0,'p',0,0,0,0,0],
[0,'l',0,0,0,0,0],
[0,'e',0,0,0,0,0],
[0,'q',0,0,0,0,0]];
function isVertically(array, word) {
var string = "";
var index = -1;
for(var i = 0; i < array.length; i++) {
var line = array[i];
for(var j = 0; j < array.length; j++) {
var element = line[j];
if(typeof element == "string") {
if(index < 0)
index = j;
if(j === index)
string += element;
}
}
}
return string == word;
}
isVertically(array1, "apple")

Getting an array with lengths of words from a sentence -javascript

I'm trying to create a function that will tell me how long the longest word in a sentence is. My approach is to split the sentence into strings of words. I now have an array of strings. My problem is that I want to use this array to get another array of numbers i.e. the length of each word. How do I do this? My code is as below but I keep getting null.
function findLongestWord(str) {
var split = str.split(" ");
for (j = 0; j < split.length; j++)
var wordCount = split[j].length;
var lengths = [];
for (var i = 0; i < wordCount.length; i++) {
lengths.push(i);
}
return Math.max(...lengths);
}
If you are going to loop through all the words you can already find the max (longest) word in your input array.
function findLongestWord(str) {
var split = str.split(" ");
var maxLength = 0;
var longestWord = ""; // If no word is found "".length will return 0
var len = split.length;
for (j = 0; j < len; j++)
{
if (split[j].length > maxLength)
{
longestWord = split[j];
maxLength = split[j].length;
}
}
return longestWord;
}
And the returned value .length to get the length (or return maxLength if you so desire).
Note depending on your application punctuation might interfere with your algorithm.
I've made some comments about the mistakes in your code
function findLongestWord(str) {
// better use .split(/\s+/) instead to remove trailing space in the middle of sentence
var split = str.split(" ");
// this for loop is redundant, you have to wrap the code that you want to loop with curly brackets.
for (j = 0; j < split.length; j++)
// the value of j would be the length of split array.
var wordCount = split[j].length;
var lengths = [];
// since wordCount.length is undefined, so loop never gets excuted and your lengths array would be empty.
for (var i = 0; i < wordCount.length; i++) {
lengths.push(i);
}
// doing Math.max on empty array will return -Infinity
return Math.max(...lengths);
}
findLongestWord('hello there mate')
Below are my solutions. There are also more ways of doing what you want to do.
function findLongestWord(str) {
// trim trailing white space.
var split = str.trim().split(/\s+/);
var lengths = [];
// loop through array of words
for (j = 0; j < split.length; j++) {
// check the length of current words
var wordCount = split[j].length;
lengths.push(wordCount);
}
return Math.max(...lengths);
}
const sentence = 'hello its a me mariooooooo';
console.log(findLongestWord(sentence))
// one liner - using reduce function
const findLongestWord2 = (str) => str.trim().split(/\s+/).reduce((a, b) => a.length > b.length ? a.length : b.length, -Infinity);
console.log(findLongestWord2(sentence))
// less efficient but shorter - using sort
const findLongestWord3 = (str) => str.trim().split(/\s+/).sort((a, b) => a.length - b.length).pop().length;
console.log(findLongestWord3(sentence))
Create a function that takes an array of words and transforms it into an array of each word's length.
function multi(arr) {
var newarr = [];
for (var i = 0; i < arr.length; i++) {
newarr.push( arr[i].length);
}
return newarr;
}
You need to use var to create j in the first for loop like you did for the second for loop with i.
This can be done using the .map() method. You map the array of strings into an array of word lengths, and then return the Math.max() of the array of lengths, like so:
function findLongestWord(str) {
// map words into array of each word's length, grab highest #
return Math.max(...str.split(" ").map(str => str.length));
}
console.log(findLongestWord("The quick brown fox jumped over the lazy dog"));

javascript loop iterating too much

Trying a fun problem of replacing vowels in a string with the next vowel in line aka a->e, e->i, i->o, o->u, not accounting for "u". Starting with an array instead of a string. My second loop (to iterate over vowel array elements) is ignoring my "j
var vowelChange = function(vowelArray, stringToChange) {
for (var i = 0; i<stringToChange.length; i++) {
for (var j = 0; j<vowelArray.length; j++) {
if (stringToChange[i]===vowelArray[j]) {
var newCharacter = vowelArray[j+1]
stringToChange[i] = newCharacter
i++
}
}
}
return stringToChange
};
I'm using node-debug to set breakpoints in a browser, and j is looping to 5 before starting over at 0. I get the correct output, but j should stop at 4...
EDIT
Can somebody explain how I'm using join incorrectly, because I can't get my function to output a string instead of just an array.
var vowelChange = function(vowelArray, stringToChange) {
for (var i = 0; i<stringToChange.length; i++) {
for (var j = 0; j<vowelArray.length-1; j++) {
if (stringToChange[i]===vowelArray[j]) {
stringToChange[i] = vowelArray[j+1]
break
}
}
}
stringToChange = stringToChange.join('')
return stringToChange
};
var vowels = ['a','e','i','o','u']
var firstName = ['t', 'e', 's', 't']
vowelChange(vowels, firstName)
console.log(firstName)
Assuming vowelArray is 0-indexed...
var vowelChange = function(vowelArray, stringToChange) {
for (var i = 0; i<stringToChange.length; i++) {
for (var j = 0; j<vowelArray.length - 1; j++) {
if (stringToChange[i]===vowelArray[j]) {
stringToChange[i] = vowelArray[j+1];
break;
}
}
}
return stringToChange
};
In JavaScript, strings are immutable objects, which means that the
characters within them may not be changed and that any operations on
strings actually create new strings.
So,if you try to change any index of the string, the original string won't change
node
> str = "hello this is dummy string";
'hello this is dummy string'
> str[0] = "w";
'w'
> str
'hello this is dummy string'
So, stringToChange[i] = vowelArray[j+1]; won't work
Could split the string and then join
var vowelChange = function(vowelArray, stringToChange) {
stringToChange = stringToChange.split('');
for(var i=0; i<stringToChange.length;i++){
for(var j=0;j<vowelArray.length-1;j++){
if(stringToChange[i] == vowelArray[j]){
stringToChange[i] = vowelArray[j+1];
break;
}
}
}
stringToChange = stringToChange.join('');
return stringToChange;
};
Example

Checking if a string contains any part of an array element

I just started learning javascript and I'm working on small chrome extension that checks a certain website's item listings for any items
that contain keywords provided by the user. I'm looking for some help on a method to compare a string to an array of strings.
So I have these variables:
var itemDetails = '[alter] saber 1/8 figure unopened';
var trackingList = ['alter figure', 'magic', 'sword art'];
I need to check if itemDetails contains any of the strings in trackingList. I know I can use indexOf() like this:
function checkArray(str, arr){
for(var i=0; i < arr.length; i++){
if(str.indexOf(arr[i]) > -1)
return true;
}
return false;
}
checkArray(itemDetails,trackingList); // returns false
However, for strings with multiple words in them, such as 'alter figure', I want checkArray() to return true as long as both of the words in the string appear anywhere in itemDetails. So checkArray() should return true in the example above since both 'alter' and 'figure' are in itemDetails.
The method I'm currently using is to split each element in trackingList:
function splitTrackList(arr){
var newarr = [];
for(var i = 0; i < arr.length; i++){
newarr[i] = arr[i].split(" ");
}
return newarr;
}
trackList = splitTrackList(trackList);
// [['alter', 'figure'], ['magic'], ['sword', 'art']]
And then compare using indexOf():
function newCheckArray(str, arr){
var passed = true;
for(var i=0; i < arr.length; i++){
for(var j=0; j < arr[i].length; j++){
if(str.indexOf(arr[i][j]) == -1){
passed = false;
break;
}
else passed = true;
}
if(passed) //stop loop if match found
break;
}
return passed;
}
newCheckArray(itemDetails,trackingList); //returns true
My method works so far but I'm guessing there is a much faster/efficient way of doing this. Please let me know what you think. Thank you in advance.
I would do something like
https://jsfiddle.net/denov/FXjXq/3/
var arr = [
"cat dog mouse",
"blue yellow green",
"pizza burrito hamburger"
];
function isInString(needle, haystack) {
return new RegExp('\\b' + needle + '\\b').test(haystack);
}
function checkForStringInArray(stringToFind, arr) {
var inString = false;
for(var i=0; i < arr.length; i++){
inString = isInString(stringToFind, arr[i]);
if(inString) break;
}
return inString;
}
var inString = checkForStringInArray('yellow', arr);
You can use regular expressions. I am giving you an example, although it is not the most efficient
function checkArray(str, arr){
for(var i=0; i < arr.length; i++){
if(str.match((".*" + arr[i].trim() + ".*").replace(" ", ".*")))
return true;
}
return false;
}
Here I alter the string "key1 keyn" to ".*key1.keyn." so it could match those keys everywhere in the string. Have in mind that this will match them if they are part of another word. Good luck.
P.S. Learn regular expressions. They are pretty important in almost every language.
This should work :
function checkArray(str, arr){
for (var j = 0; j < arr.length;j++) {
wordtab = splitTrackList(arr[j]);
for(var i=0; i < tab.length; i++){
if(str.indexOf(wordtab[i]) > -1)
return true;
}
}
return false;
}
Here is a solution with lambda expressions:
var itemDetails = '[alter] saber 1/8 figure unopened';
var trackingList = ['alter saber', 'magic', 'sword art'];
var trackingList2 = ['alter was', 'magic', 'sword art'];
if(trackingList.map(str => str.split(" ")).filter(arrtemp => arrtemp.filter(strin => itemDetails.indexOf(strin) > -1).length == arrtemp.length).length > 0) {
console.debug("true");
} else {
console.debug("false")
}
if(trackingList2.map(str => str.split(" ")).filter(arrtemp => arrtemp.filter(strin => itemDetails.indexOf(strin) > -1).length == arrtemp.length).length > 0) {
console.debug("true");
} else {
console.debug("false")
}
https://jsfiddle.net/wrz1m0b5/
The regex solution only works if words are in correct order.

Categories