Insert multiple elements into array with splice method - javascript

I have a problem I'm trying to solve. I am trying to insert a space where ever there is a instance of a capital letter. The problem is that the space is pushed into the correct index but for all other instances where a capital letter appears, it doesn't apply that space. I have researched extensively about the splice methods but could not figure out a solution to my problem. Can someone point me in the right direction.
function solution(string) {
let splitStr = [...string];
for(let i = 0; i < splitStr.length; i++) {
if(!splitStr[i].toUpperCase()) return
if(splitStr[i] === splitStr[i].toUpperCase()) {
let indexOfCapLetter = splitStr.indexOf(splitStr[i].toUpperCase());
splitStr.splice(indexOfCapLetter, 0, ' ' );
return splitStr
}
}
}

First issue is that you're returning the array inside your if statement within the loop. This escapes the function after the first capital letter. But after that there's another issue.
Whenever you add a new element to the array, the characters after it are moved to a higher index.
To counter this you can loop through the array backwards so the affected elements are always ones you've already parsed:
function solution(string) {
let splitStr = [...string];
for(let i = splitStr.length-1; i >=0; i--) {
if(splitStr[i] === splitStr[i].toUpperCase()) {
splitStr.splice(i, 0, ' ' );
}
}
return splitStr.join('');
}
console.log(solution('HelloWorldLongString'))

Related

Splice method don't properly

My splice method don't work here (don't give my code attention just I want to know why this code don't work in my console).
function capSpace(txt) {
// write your code here
wordSplit = txt.split("");
for (let i = 0; i < wordSplit.length; i++) {
if (wordSplit[i].toUpperCase() == wordSplit[i]) {
wordSplit.splice(5, 0, " ")
}
}
return wordSplit
}
console.log(capSpace("fausJkalMalkihkLhb"));
First of all, you need to increment the i for each character that you add to the array.
I assume you're trying to add a space before each capital letter, in which case you need to add it at the i index, not the 5th index.
function capSpace(txt) {
// write your code here
wordSplit = txt.split("");
for (let i = 0; i < wordSplit.length; i++) {
if (wordSplit[i].toUpperCase() == wordSplit[i]) {
wordSplit.splice(i, 0, " ");
i++;
}
}
return wordSplit
}
var result = capSpace("fausJkalMalkihkLhb").join('');
console.log(result);
The splice method is adding an empty space to the wordSplit array in your snippet found here:
wordSplit.splice(5, 0, " ")
This is incrementing the length of wordSplit on each iteration and the condition of the for loop:
i < wordSplit.length
will never be satisfied because the length of wordSplit increases which creates an infinite loop and therefore is never able to return wordSplit and therefore never able to console.log the variable of result because it's stuck in an infinite loop.

How to find the missing next character in the array?

I have an array of characters like this:
['a','b','c','d','f']
['O','Q','R','S']
If we see that, there is one letter is missing from each of the arrays. First one has e missing and the second one has P missing. Care to be taken for the case of the character as well. So, if I have a huge Object which has all the letters in order, and check them for the next ones, and compare?
I am totally confused on what approach to follow! This is what I have got till now:
var chars = ("abcdefghijklmnopqrstuvwxyz"+"abcdefghijklmnopqrstuvwxyz".toUpperCase()).split("");
So this gives me with:
["a","b","c","d","e","f","g","h","i","j","k","l","m",
"n","o","p","q","r","s","t","u","v","w","x","y","z",
"A","B","C","D","E","F","G","H","I","J","K","L","M",
"N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
Which is awesome. Now my question is, how do I like check for the missing character in the range? Some kind of forward lookup?
I tried something like this:
Find the indexOf starting value in the source array.
Compare it with each of them.
If the comparison failed, return the one from the original array?
I think that a much better way is to check for each element in your array if the next element is the next char:
function checkMissingChar(ar) {
for (var i = 1; i < ar.length; i++) {
if (ar[i].charCodeAt(0) == ar[i-1].charCodeAt(0)+1) {
// console.log('all good');
} else {
return String.fromCharCode(ar[i-1].charCodeAt(0)+1);
}
}
return true;
}
var a = ['a','b','c','d','f']
var b = ['O','Q','R','S']
console.log(checkMissingChar(a));
console.log(checkMissingChar(b));
Not that I start to check the array with the second item because I compare it to the item before (the first in the Array).
Forward Look-Ahead or Negative Look-Ahead: Well, my solution would be some kind of that. So, if you see this, what I would do is, I'll keep track of them using the Character's Code using charCodeAt, instead of the array.
function findMissingLetter(array) {
var ords = array.map(function (v) {
return v.charCodeAt(0);
});
var prevOrd = "p";
for (var i = 0; i < ords.length; i++) {
if (prevOrd == "p") {
prevOrd = ords[i];
continue;
}
if (prevOrd + 1 != ords[i]) {
return String.fromCharCode(ords[i] - 1);
}
prevOrd = ords[i];
}
}
console.log(findMissingLetter(['a','b','c','d','f']));
console.log(findMissingLetter(['O','Q','R','S']));
Since I come from a PHP background, I use some PHP related terms like ordinal, etc. In PHP, you can get the charCode using the ord().
As Dekel's answer is better than mine, I'll try to propose somewhat more better answer:
function findMissingLetter (ar) {
for (var i = 1; i < ar.length; i++) {
if (ar[i].charCodeAt(0) != ar[i-1].charCodeAt(0)+1) {
return String.fromCharCode(ar[i-1].charCodeAt(0)+1);
}
}
return true;
}
var a = ['a','b','c','d','f']
var b = ['O','Q','R','S']
console.log(findMissingLetter(a));
console.log(findMissingLetter(b));
Shorter and Sweet.

trouble with Javascript while loop, what am I doing wrong?

So I am doing a an exercise in which I have to sort a given string. Each word in the string contains a number in it(written like this 'H3llo'). The number that is in each word of the string should be placed in order according to the number in the new string that is to be returned.
For example if my input is "is2 Thi1s T4est 3a", then my function should return "Thi1s is2 3a T4est".
I almost cracked it but my output is incomplete. Here is my code:
function order(words) {
var lst = words.split(' ');
var count = 0;
var n = count + 1;
var s_n = n.toString();
var new_l = [];
while (count < lst.length) {
if (lst[count].includes(s_n) === true) {
new_l.push(lst[count])
}
count++
}
return new_l.join(' ');
}
When I test it, instead of getting:
console.log(order("is2 Thi1s T4est 3a"));
>>> 'Thi1s is2 3a T4est'
I get this:
console.log(order("is2 Thi1s T4est 3a"));
>>> 'Thi1s'
Can anyone explain to me what I am doing wrong?
You will basically need two loops - one for your current counter count i.e. the incremental number and another to iterate over the list of words to match that number. You increase the count only after you have finished iterating over the list.
function order(words) {
var lst = words.split(' ');
var count = 0;
var new_l = [];
while (count <= lst.length) {
for (i = 0; i < lst.length; i++) {
if (lst[i].includes(count)) {
new_l.push(lst[i])
}
}
count++;
}
return new_l.join(' ');
}
console.log(order("is2 Thi1s T4est 3a"));
Notice too that you don't need s_n -- the conversion is implicit, and you don't need === true as this is implicit in the if statement.
The main thing you are doing wrong is that you assign s_n to the string '1' before your loop, but you never update it within the loop. At the same time as you update count, you need to update s_n to the string of the next integer.
So you 'fixed' the part where you weren't updating the value of n or s_n within your outer loop, but the code still wont't work because you are now using count both to increment the digit you are looking for (within a word) and to increment the search through the list of words. You need an inner loop (and another variable) to increment the search.

indexOf ignores second character in array

I'm just studying JS and I need to write a program that checkes if the string in the first element of the array contains all of the letters of the string in the second element of the array.
I've made a code like this:
function mutation(arr) {mutation: {
var lowerCaseStringOne = arr[0].toLowerCase();
var lowerCaseStringTwo = arr[1].toLowerCase();
if (lowerCaseStringOne === lowerCaseStringTwo) {
console.log(true);
break mutation;
}
var newArray = [];
for (var i = 0; i < lowerCaseStringTwo.length; i++){
console.log(lowerCaseStringTwo[i]);
if (lowerCaseStringTwo.indexOf(lowerCaseStringOne[i]) > 0) {
newArray.push(lowerCaseStringTwo[i]);
console.log('---');
}
}
var result = newArray.join("");
if (result === lowerCaseStringTwo) {
console.log(true);
} else {
console.log(false);
}
}
}
mutation(["Mary", "Aarmy"]);
I think it's very complicated, but I can't solve the problem - the "indexOf" function seems to ignore a second character in my loop - loggs it in the console but doesn't pushes into an array. I thought it could happen because first and second letters are similar, but it's not. No matter what letter, it just ignores it.
indexOf() will return 0 for the letter "a" in your example as the first instance is at position 0 in the array.
You should be using ">= 0"

Can anyone see what is wrong with my Javascript?

I have written the following:
var pages=["[www.google.co.uk] This is the WWW. ","[www.yahoo.co.uk] This is also the WWW. "];
function findScoresC(s){
var scores=[];
var words=[];
var wordScore;
var indexScore=[];
s=s.toLowerCase();
for(i=0;i<pages.length; i++){
var lowerCaseContents=(pages[i].substring(pages[i].indexOf("]")+1,pages[i].lastIndexOf(" "))).toLowerCase();
words=lowerCaseContents.split(" ");
for(i=0;i<words.length;i++){
if(words[i].match(s)){
wordScore=1;
indexScore[i]=indexScore[i]+1};
scores[i] =indexScore[i]}};
return scores;
}
alert(findScoresC("w"));
The function aims to return an array ("scores") where each index of the array is the number of times the string s is found in each index of the "pages" array, excluding what is inside the square brackets - however, only finding the string s once within each word. So ideally, the first index of scores would be 1, because I have called the function with the letter w, and i would only like it to find the first w of "WWW" in the first index of pages - if this makes sense.
I have confused myself pretty epically in getting this far, so I have no idea why the function is returning ",,,," rather than numerical values for each index of scores - any ideas?
Thanks
When your for loop exits, i is equal to words.length, which is one greater than the last index of indexScore. You are assigning nothing at all to scores[i] each time through.
It might be because you have a nested for loop with the same index variable.
var pages=["[www.google.co.uk] This is the WWW. ","[www.yahoo.co.uk] This is also the WWW. ";
function findScoresC(s){
var scores=[];
var words=[];
s=s.toLowerCase();
for(i=0;i<pages.length; i++)
{
scores[i]=0;
var lowerCaseContents=(pages[i].substring(pages[i].indexOf("]")+1,pages[i].lastIndexOf(" "))).toLowerCase();
words=lowerCaseContents.split(" ");
for(j=0;j<words.length;j++)
{
if(words[j].match(s))
{
scores[i] += 1;
}
}
}
return scores;
}
alert(findScoresC("w"));
There were a few things. I replaced "i" with "j" for the inner index. You don't require a semicolon after a closing paren. You should have a semicolon after instructions (a couple were missing).
Probably the main issue (after the "i" issue) was that scores[i] should have been set outside the inner loop. This would have been clearer if the cosing parens had been separated out onto separate lines, instead of like "scores[i] =indexScore[i]}};".
It turned out that the variable indexScore was not required. That allowed me to bring scores[i] inside the inner loop to accumulate word hits directly.
Finally, I would prefer to communicate the pages variable to the function as an argument than to assume that it is available in the global space. I tend to avoid globals if I can.
var pages = [...];
function findScoresC(pages, s)
{
...
}
alert(findScoresC(pages, "w"));
Here's you're function fixed. It returns [1,1] which appears to be what you were going for. My notes are in the code.
var pages=["[www.google.co.uk] This is the WWW. ","[www.yahoo.co.uk] This is also the WWW. "];
function findScoresC(s){
var scores = [],
words = [],
wordScore;
// indexScore = [] <- this doesn't seem necessary
s = s.toLowerCase();
// Make sure to use `var i` and not just `i`; otherwise, you are creating a global variable.
for ( var i=0; i<pages.length; i++ ) {
// Initialize me!
scores.push(0);
var lowerCaseContents = pages[i].substring(
pages[i].indexOf("]") + 1, pages[i].lastIndexOf(" ")
).toLowerCase();
words = lowerCaseContents.split(" ");
// You were using `i` for this loop as well. No can do.
for ( var j=0; j<words.length; j++) {
if ( words[j].match(s) ) {
// wordScore = 1; <- I don't know what you're using this for
scores[i]++;
}
}
};
return scores;
}
console.log(findScoresC("w"));
here's a small function that counts how many times substring "subStr" occurs in "str", not counting [...]
function substrCount(str, subStr) {
var str = str.replace(/\[.+?\]/g, "");
var del = str.toLowerCase().split(subStr.toLowerCase()).join("");
return (str.length - del.length) / subStr.length;
}
the rest is obvious ;)
// edit: this is how you apply this function to an array
var someArray = ["whatever", "something", "else" ];
var counter = [];
for(var i = 0; i < someArray; i++)
counter[i] = substrCount(someArray[i], "something");
// or, to count only one match, i.e. just to test if a substring is present
counter[i] = substrCount(someArray[i], "something") > 0;

Categories

Resources