For loop to check the first letter in an array - javascript

I am trying to use a for loop to loop through an array and check the first letter of each word in the array and check to see if it starts with an M, but I can't seem to figure out how to correctly set that up.
So far I have this:
for (var animalsName = cats[0]; animalsName <= cats; animalsName++){
if (animalsName.charAt(0) == 'M') {
console.log("No treat for " + animalsName + ".");
} else {
console.log(animalsName + " loved their treat!");
}
}

You are very close.
I have made minor change in the for loop to iterate correctly and fetch the first character of the animal name.
var cats = [];
cats.push('mname1');
cats.push('tname1');
cats.push('mname2');
cats.push('Mname3');
for (var index = 0; index < cats.length; index++){
var animalsName = cats[index];
if (animalsName.substr(0,1).toLowerCase() === 'm') {
console.log("No treat for " + animalsName + ".");
} else {
console.log(animalsName + " loved their treat!");
}
}

for (let i = 0; i < cats.length; i += 1) {
if (cats[i].charAt(0).toLowerCase() === 'm') {
// do whatever you want
}
}
This will loop over the cats array and check the first letter--charAt(0)--of each element in the array. If the first letter, converted to lower case, is 'm', then you do whatever you want.

Related

JavaScript: Return index position as 1 instead of 0

Given an array of strings, I am tasked with returning a string with "The lucky person is number n in the list!" if the string "lucky" appears within the array.
I have working code for this, however it is asking me to return "The lucky person is number 1 in the list!" when arr = ["lucky"].
So far this is returning "person is number 0" as it is index position 0, so how can I alter the code to make this position count as 1 instead? Thank you!
function findLuckyPerson(arr) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] === 'lucky') {
return "The lucky person is number " + arr.indexOf("lucky", 0) + " in the list!";
} else {
return "There is no lucky person in the list :("
}
}
}
(i + 1) instead of arr.indexOf("lucky", 0) should do the trick.
Even more concise, get rid of the loop altogether
function findLuckyPerson(arr) {
var i = arr.indexOf("lucky");
if (i >= 0)
return "The lucky person is number " + (i + 1) + " in the list!";
else
return "There is no lucky person in the list :("
}
You can add 1 in index position like following:
var arr=['lucky','unlucky'];
function findLuckyPerson(arr) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] === 'lucky') {
return "The lucky person is number " + (i+1) + " in the list!";
} else {
return "There is no lucky person in the list :("
}
}
}
console.log(findLuckyPerson(arr));

Find duplicate phrases (not just words) in array

Let's say I have an array:
[
"I want **a dog**",
"**A dog** is here",
"Pet **a dog**",
"A **red cat**",
"**red cat** is cute"
...
]
How do I figure out what the duplicate phrases are, not just words?
For example, I'd like "a dog" and "red cat" to be returned.
Most existing posts I found are only about getting individual words, not phrases (multiple words).
You're giving us too little information. I'm assuming you're splitting by spaces. ES6 to the rescue :). Sets have O(1) lookup for when you're looking for repeated phrases.
edit: Just realized that you can cut down space complexity by a ton with some small modifications. If you want me to do that, give me a shoutout.
const buildAllPhrases = sentence => {
const splitSentence = sentence.split(" ")
const phraseSize = splitSentence.length
const allPhrases = []
for (let i = phraseSize; i > 0; i--) {
for (let y = 0; y + i <= phraseSize; y++) {
allPhrases.push(splitSentence.slice(y, y + i))
}
}
return allPhrases.map(phrase => phrase.join(" "))
}
const findRepeats = sentences => {
const allPhrases = new Set()
const repeatedPhrases = new Set()
let phrases
sentences.forEach(phrase => {
phrases = buildAllPhrases(phrase)
phrases.forEach(subPhrase => {
if (allPhrases.has(subPhrase)) {
repeatedPhrases.add(subPhrase)
} else {
allPhrases.add(subPhrase)
}
})
})
return [...repeatedPhrases]
}
const sample = [
"I want **a dog**",
"**A dog** is here",
"Pet **a dog**",
"A **red cat**",
"**red cat** is cute"
]
findRepeats(sample)
//['dog**', '**a dog**', '**a', '**red cat**', '**red', 'cat**', 'is']
This is not final version of the javascript function, and it can be optimized further. Few changes may also be required, but it can be starter for your requirement.
function GetPhrases(stringsArray) {
//Array to split your string into words.
var jaggedArray = [];
//Array to keep indexes of strings where 2 matching words are found together.
var newArray = [];
var phrases = [];
//Loop through your array
for (var ic = 0; ic < stringsArray.length; ic++) {
//Convert every item to array of strings
var items = (stringsArray[ic]).split(" ");
for (var it = 0; it < items.length; it++)
items[it] = items[it].toLowerCase();
//Push the array of words to main array
jaggedArray.push(items);
}
//console.log(jaggedArray);
// Loop through the main array
for (var iLoop = 0; iLoop < jaggedArray.length; iLoop++) {
// For every item in main array, loop through words in that item.
for (var ik = 0; ik < jaggedArray[iLoop].length; ik++) {
var currentWord = jaggedArray[iLoop][ik];
// For every word, check its existence in the main array in all items coming after current item.
for (var il = iLoop + 1; il < jaggedArray.length; il++) {
// Find the index in the string.
var indexOfFind = jaggedArray[il].indexOf(currentWord);
if (indexOfFind > 0) {
// if matching index is more than 0, find if the word before this word also matches.
var indexofPrevWord = jaggedArray[il].indexOf(jaggedArray[iLoop][ik - 1]);
if ((indexofPrevWord >= 0) && (indexofPrevWord == (indexOfFind - 1)))
if (newArray.indexOf(il + " - " + iLoop) < 0)
newArray.push(il + " - " + iLoop);
// if matching index is more than 0, find if the word after this word also matches.
var indexofNextWord = jaggedArray[il].indexOf(jaggedArray[iLoop][ik + 1]);
if (indexofNextWord >= 0 && (indexofNextWord == (indexOfFind + 1)))
if (newArray.indexOf(il + " - " + iLoop) < 0)
newArray.push(il + " - " + iLoop);
}
else if (indexOfFind = 0) {
// if matching index is more than 0, find if the word after this word also matches.
var indexofNewWord = jaggedArray[il].indexOf(jaggedArray[iLoop][ik + 1]);
if (indexofNewWord >= 0 && (indexofNewWord == (indexOfFind + 1)))
if (newArray.indexOf(il + " - " + iLoop) < 0)
newArray.push(il + " - " + iLoop);
}
}
}
}
//newArray will store indexes of those string arrays in jagged array which has a matching sequence of atleast 2 words.
//console.log(newArray);
//Loop through newArray
for (var itl = 0; itl < newArray.length; itl++) {
var item = newArray[itl];
var values = item.split(" - ");
var firstArrayItem = jaggedArray[values[0]];
var secondArrayItem = jaggedArray[values[1]];
var phraseStartPoint = [];
//for every word in firstItem
for (var iy = 0; iy < firstArrayItem.length - 1; iy++) {
var t = iy + 1;
// check if that word and next word exist in second array
if (secondArrayItem.toString().indexOf(firstArrayItem[iy] + "," + firstArrayItem[t]) >= 0) {
// if they do exist, get the indexes of these and store in local array, if they are not there, since we do not want repeating words later.
if (phraseStartPoint.indexOf(iy) < 0)
phraseStartPoint.push(iy);
if (phraseStartPoint.indexOf(t) < 0)
phraseStartPoint.push(t);
}
}
var str = "";
// Prepare the phrase from the local array and push into phrases array, if it not exists there.
for (var ifinalLoop = 0; ifinalLoop < phraseStartPoint.length; ifinalLoop++) {
str = str + firstArrayItem[phraseStartPoint[ifinalLoop]] + " ";
}
if (phrases.indexOf(str) < 0)
phrases.push(str);
}
return phrases;
}
var stringsArray = [
"I want a dog",
"A dog is here",
"Pet a dog is cute",
"A red cat is here",
"red cat is cute"
];
var result = GetPhrases(stringsArray);
// Print the phrases array.
for (var iPhrase = 0; iPhrase < result.length; iPhrase++) {
console.log(result[iPhrase]);
}
with regex you can detect duplicates in strings.
According to this regex:
(?:.*?)(\b\w.{3,}\b)(?:.*?)(\1) ,
it only works if you're looking for twice the same pattern.
note: you can replace 3 in {3,} by any other integer and see the changes.
This paramater contrains the minimal string lenght you're looking for twice.

Browser crashing while loop JavaScript algorithm

Guys i'm trying to write an algorithm where I pass in a large string and let it loop through the string and whatever palindrome it finds, it pushes into array but for some reason my browser is crashing once i put in the while loop and I have no
function arrOfPalindromes(str) {
var palindromeArrays = []
var plength = palindromeArrays.length
// grab first character
// put that in a temp
// continue and look for match
// when match found go up one from temp and down one from index of loop
// if matched continue
// else escape and carry on
// if palendrome push into array
var counter = 0;
for (var i = 0; i < str.length; i++) {
for (var j = 1; j < str.length - 1; j++) {
if (str[i + counter] === str[j - counter]) {
while (str[i + counter] === str[j - counter]) {
console.log(str[j], str[i])
// append the letter to the last index of the array
palindromeArrays[plength] += str[i]
counter++
}
}
}
}
return palindromeArrays
}
var result2 = arrOfPalindromes('asdfmadamasdfbigccbigsdf')
console.log(result2)
Do not mention about the algorithm but the condition
while (str[i + counter] === str[j - counter])
Make your code crash. A little surprise but str[j+counter] when j+counter > str.length return undefined and the same as j-counter <0. There for, your while loop never end because of undefined === undefined.
Returning same sized array to handle nested palis.
ex: abxyxZxyxab => 00030703000 odd numbered nested palis.
ex: asddsa => 003000 even numbered pali.
ex: asdttqwe => 00020000 i dont know if this is a pali but here we go
smallest pali is 2 char wide so i start at index:1 and increment till str.len-1
for (var i = 1; i < str.length-1; i++) {
counter=0;
while(str[i]+1-counter == str[i]+counter || str[i]-counter == str[i]+counter) { // always true when counter is 0
// while (even numbered palis || odd numbered palis)
// IF counter is bigger than 0 but we are still here we have found a pali & middle of the pali is i(or i+0.5) &size of the pali is counter*2(or+1)
if(str[i]+1-counter == str[i]+counter){//even sized pali
res[i]=counter*2;
}else{//odd sized pali
res[i]=counter*2+1;
}
counter++;//see if its a bigger pali.
}
}
not super optimized while + if,else checks same stuff. These can be somehow merged. Maybe even even and odd can be handled without any checks.
You don't need to use three loops. You can do it with two for loops where one starts from the beginning and other one is from the end of the string.
Here we use array reverse() method to match palindromes.
Also I added additional minLength parameter and duplication removal logic to make it more nice.
function findPalindromes(str, minLength) {
var palindromes = [];
var _strLength = str.length;
for (var i = 0; i < _strLength; i++) {
for (var j = _strLength - 1; j >= 0; j--) {
if (str[i] == str[j]) {
var word = str.substring(i, j + 1);
//Check if the word is a palindrome
if (word === word.split("").reverse().join("")) {
//Add minimum length validation and remove duplicates
if(word.length >= minLength && palindromes.indexOf(word) === -1){
palindromes.push(word);
}
}
}
}
}
return palindromes;
}
var result = findPalindromes('asdfmadamasdfbigccbigsdf', 2)
console.log(result)

Showing unique characters in a string only once

I have a string with repeated letters. I want letters that are repeated more than once to show only once.
Example input: aaabbbccc
Expected output: abc
I've tried to create the code myself, but so far my function has the following problems:
if the letter doesn't repeat, it's not shown (it should be)
if it's repeated once, it's show only once (i.e. aa shows a - correct)
if it's repeated twice, shows all (i.e. aaa shows aaa - should be a)
if it's repeated 3 times, it shows 6 (if aaaa it shows aaaaaa - should be a)
function unique_char(string) {
var unique = '';
var count = 0;
for (var i = 0; i < string.length; i++) {
for (var j = i+1; j < string.length; j++) {
if (string[i] == string[j]) {
count++;
unique += string[i];
}
}
}
return unique;
}
document.write(unique_char('aaabbbccc'));
The function must be with loop inside a loop; that's why the second for is inside the first.
Fill a Set with the characters and concatenate its unique entries:
function unique(str) {
return String.prototype.concat.call(...new Set(str));
}
console.log(unique('abc')); // "abc"
console.log(unique('abcabc')); // "abc"
Convert it to an array first, then use Josh Mc’s answer at How to get unique values in an array, and rejoin, like so:
var nonUnique = "ababdefegg";
var unique = Array.from(nonUnique).filter(function(item, i, ar){ return ar.indexOf(item) === i; }).join('');
All in one line. :-)
Too late may be but still my version of answer to this post:
function extractUniqCharacters(str){
var temp = {};
for(var oindex=0;oindex<str.length;oindex++){
temp[str.charAt(oindex)] = 0; //Assign any value
}
return Object.keys(temp).join("");
}
You can use a regular expression with a custom replacement function:
function unique_char(string) {
return string.replace(/(.)\1*/g, function(sequence, char) {
if (sequence.length == 1) // if the letter doesn't repeat
return ""; // its not shown
if (sequence.length == 2) // if its repeated once
return char; // its show only once (if aa shows a)
if (sequence.length == 3) // if its repeated twice
return sequence; // shows all(if aaa shows aaa)
if (sequence.length == 4) // if its repeated 3 times
return Array(7).join(char); // it shows 6( if aaaa shows aaaaaa)
// else ???
return sequence;
});
}
Using lodash:
_.uniq('aaabbbccc').join(''); // gives 'abc'
Per the actual question: "if the letter doesn't repeat its not shown"
function unique_char(str)
{
var obj = new Object();
for (var i = 0; i < str.length; i++)
{
var chr = str[i];
if (chr in obj)
{
obj[chr] += 1;
}
else
{
obj[chr] = 1;
}
}
var multiples = [];
for (key in obj)
{
// Remove this test if you just want unique chars
// But still keep the multiples.push(key)
if (obj[key] > 1)
{
multiples.push(key);
}
}
return multiples.join("");
}
var str = "aaabbbccc";
document.write(unique_char(str));
Your problem is that you are adding to unique every time you find the character in string. Really you should probably do something like this (since you specified the answer must be a nested for loop):
function unique_char(string){
var str_length=string.length;
var unique='';
for(var i=0; i<str_length; i++){
var foundIt = false;
for(var j=0; j<unique.length; j++){
if(string[i]==unique[j]){
foundIt = true;
break;
}
}
if(!foundIt){
unique+=string[i];
}
}
return unique;
}
document.write( unique_char('aaabbbccc'))
In this we only add the character found in string to unique if it isn't already there. This is really not an efficient way to do this at all ... but based on your requirements it should work.
I can't run this since I don't have anything handy to run JavaScript in ... but the theory in this method should work.
Try this if duplicate characters have to be displayed once, i.e.,
for i/p: aaabbbccc o/p: abc
var str="aaabbbccc";
Array.prototype.map.call(str,
(obj,i)=>{
if(str.indexOf(obj,i+1)==-1 ){
return obj;
}
}
).join("");
//output: "abc"
And try this if only unique characters(String Bombarding Algo) have to be displayed, add another "and" condition to remove the characters which came more than once and display only unique characters, i.e.,
for i/p: aabbbkaha o/p: kh
var str="aabbbkaha";
Array.prototype.map.call(str,
(obj,i)=>{
if(str.indexOf(obj,i+1)==-1 && str.lastIndexOf(obj,i-1)==-1){ // another and condition
return obj;
}
}
).join("");
//output: "kh"
<script>
uniqueString = "";
alert("Displays the number of a specific character in user entered string and then finds the number of unique characters:");
function countChar(testString, lookFor) {
var charCounter = 0;
document.write("Looking at this string:<br>");
for (pos = 0; pos < testString.length; pos++) {
if (testString.charAt(pos) == lookFor) {
charCounter += 1;
document.write("<B>" + lookFor + "</B>");
} else
document.write(testString.charAt(pos));
}
document.write("<br><br>");
return charCounter;
}
function findNumberOfUniqueChar(testString) {
var numChar = 0,
uniqueChar = 0;
for (pos = 0; pos < testString.length; pos++) {
var newLookFor = "";
for (pos2 = 0; pos2 <= pos; pos2++) {
if (testString.charAt(pos) == testString.charAt(pos2)) {
numChar += 1;
}
}
if (numChar == 1) {
uniqueChar += 1;
uniqueString = uniqueString + " " + testString.charAt(pos)
}
numChar = 0;
}
return uniqueChar;
}
var testString = prompt("Give me a string of characters to check", "");
var lookFor = "startvalue";
while (lookFor.length > 1) {
if (lookFor != "startvalue")
alert("Please select only one character");
lookFor = prompt(testString + "\n\nWhat should character should I look for?", "");
}
document.write("I found " + countChar(testString, lookFor) + " of the<b> " + lookFor + "</B> character");
document.write("<br><br>I counted the following " + findNumberOfUniqueChar(testString) + " unique character(s):");
document.write("<br>" + uniqueString)
</script>
Here is the simplest function to do that
function remove(text)
{
var unique= "";
for(var i = 0; i < text.length; i++)
{
if(unique.indexOf(text.charAt(i)) < 0)
{
unique += text.charAt(i);
}
}
return unique;
}
The one line solution will be to use Set. const chars = [...new Set(s.split(''))];
If you want to return values in an array, you can use this function below.
const getUniqueChar = (str) => Array.from(str)
.filter((item, index, arr) => arr.slice(index + 1).indexOf(item) === -1);
console.log(getUniqueChar("aaabbbccc"));
Alternatively, you can use the Set constructor.
const getUniqueChar = (str) => new Set(str);
console.log(getUniqueChar("aaabbbccc"));
Here is the simplest function to do that pt. 2
const showUniqChars = (text) => {
let uniqChars = "";
for (const char of text) {
if (!uniqChars.includes(char))
uniqChars += char;
}
return uniqChars;
};
const countUnique = (s1, s2) => new Set(s1 + s2).size
a shorter way based on #le_m answer
let unique=myArray.filter((item,index,array)=>array.indexOf(item)===index)

Loop & search through ALL items in localStorage

I'm trying to loop through localStorage to get ALL items through localStorage.length that works with my search algorithm. If i change: i < localStorage.length inside the for loop to simply a number, i.e: for (i=0; i<100; i++) instead of: (i=0; i<=localStorage.length-1; i++), everthing works. However, I do realize the problem might lie in the search algorithm.
The code getting all items:
var name = new Array();
for (var i = 0; i <= localStorage.length - 1; i++) { // i < 100 works perfectly
key = localStorage.key(i);
val = localStorage.getItem(key);
value = val.split(","); //splitting string inside array to get name
name[i] = value[1]; // getting name from split string
}
My working (!?) search algorithm:
if (str.length == 0) {
document.getElementById("searchResult").innerHTML = "";
}
else {
if(str.length > 0) {
var hint = "";
for(var i=0; i < name.length; i++) {
if(str.toLowerCase() == (name[i].substr(0, str.length)).toLowerCase()) { //not sure about this line
if(hint == "") {
hint = name[i];
} else {
hint = hint + " <br /> " + name[i];
}
}
}
}
}
if(hint == "") {
document.getElementById("searchResult").innerHTML=str + " står inte på listan";
} else {
document.getElementById("searchResult").innerHTML = hint;
}
}
What is wrong with my localStorage.length, or what is wrong with the search algorithm?
localStorage is an object, not an array.
Try for(var i in window.localStorage):
for(var i in window.localStorage){
val = localStorage.getItem(i);
value = val.split(","); //splitting string inside array to get name
name[i] = value[1]; // getting name from split string
}
Problem now SOLVED. The issue was that each time data was saved to localStorage, one extra empty item was stored at the bottom of the local db as a consequence of an incorrectly written for loop (in the setItem part.) arrayIndex < guestData.length should have been arrayIndex < guestData.length-1. arrayIndex < guestData.length-1 stores all items without creating an empty item at the bottom of the database which later messed up the search algorithm, as the last value to be search was undefined (the empty item).
print all localStorage items
and exclude the internal properties and methods.
for(var key in localStorage){
if(localStorage.hasOwnProperty(key)) {
console.log(key + ' : ' + localStorage.getItem(key));
}
}

Categories