Function only returning first letter capitalised - javascript

I have a function that is meant to do this:
accum("abcd"); // "A-Bb-Ccc-Dddd"
accum("RqaEzty"); // "R-Qq-Aaa-Eeee-Zzzzz-Tttttt-Yyyyyyy"
We can see the first "for" loop repeats each substring by it's current (index + 1). It pushes it to the array and the output would be [ 'a', 'bb', 'ccc', 'dddd' ]
It is then obvious that I need to iterate over this array and capitalise each string which I have done by the second for loop below.
The problem is when I return the array it is returning like this: [ 'A', 'B', 'C', 'D' ]
It is returning the first substring of each string but it isn't returning the rest of them.
function accum(s) {
var splitstring = s.split("")
var newarray = []
for(var i = 0; i < splitstring.length; i++) {
newarray.push(splitstring[i].repeat(i + 1))
}
for (var i = 0; i < newarray.length; i++) {
newarray[i] = newarray[i].charAt(0).toUpperCase()
}
return newarray
}
accum("abcd")

That's because you're overwriting the string with only the first character. you need to concatenate the rest of the string.
for (var i = 0; i < newarray.length; i++) {
newarray[i] = newarray[i].charAt(0).toUpperCase() + newarray[i].slice(1);
}
Here's a shorter version of your code:
function accum(s) {
return s.split("").map((ss, i) => ss.toUpperCase() + ss.repeat(i)).join("-");
}
console.log(accum("abcd"));
It also adds the separator that you seem to want. If you actually wanted the array, then remove .join("-").

No need to use second for loop. Just use map() on the returned array.
function accum(s) {
var splitstring = s.split("");
var newarray = [];
for(var i= 0; i < splitstring.length; i++) {
newarray.push(splitstring[i].repeat(i + 1))
}
return newarray.map(j=>j[0].toUpperCase()+ j.slice(1)).join('-');
}
console.log(accum("abcd"));

Related

Why is my nested loop only finding one duplicate character in a string?

My apologies if this is a duplicate, I couldn't find an answer after searching for a while on Stackoverflow.
I am trying to use a nested loop to find any duplicate characters in a string.
So far, all I can manage to do is to find one duplicate the string.
For example, when I try the string "aabbcde", the function returns ['a', 'a'], whereas I was expecting ['a', 'a', 'b', 'b'].
I obviously have an error in my code, can anybody help point me towards what it could be?
const myStr = "aabbcde";
function duplicateCount(text){
const duplicates = [];
for (let i = 0; i < text.length; i++) {
for (let j = 0; j < text[i].length; j++) {
if (text[i] === text[j]) {
duplicates.push(text[i]);
}
}
}
return duplicates;
}
duplicateCount(myStr);
It should be something like this.
issues in this loop for (let j = 0; j < text[i].length; j++)
const myStr = "aabbcde";
function duplicateCount(text){
const duplicates = [];
for (let i = 0; i < text.length; i++) {
for (let j = i+1; j < text.length; j++) {
if (text[i] === text[j]) {
duplicates.push(text[i]);
}
}
}
return duplicates;
}
console.log(duplicateCount(myStr));
Using nested loop will make it very hard to do it,we can use a Object to store the appear count,and then filter the count
const myStr1 = "aabbcde";
const myStr2 = "ffeddbaa";
const duplicateCount = str => {
let map = {}
for(c of str){
map[c] = (map[c]??0) + 1
}
let result = []
for(m in map){
if(map[m] <= 1){
continue
}
result.push(...Array(map[m]).fill(m))
}
return result
}
console.log(duplicateCount(myStr1))
console.log(duplicateCount(myStr2))
You can simply achieve the result you're looking for by creating an object map of the string (meaning each key of the object will be each unique character of the string and their associated values will be the number of times each character is repeated in the string).
After you create an object map of the string, you can loop through the object and check if each value is greater than one or not. If they're you would push that item into a result array by the number of times the character is repeated. Please find my code here:
const myStr = 'aabbcde';
const duplicateCount = (str) => {
const result = [];
const obj = {};
str.split('').map((char) => {
obj[char] = obj[char] + 1 || 1;
});
for (key in obj) {
if (obj[key] > 1) {
for (let i = 0; i < obj[key]; i++) {
result.push(key);
}
}
}
return result;
};
console.log(duplicateCount(myStr));

To finish the function scrollingText(word)

I am writing a program where I want the following result:
[ 'ROBOT',
'OBOTR',
'BOTRO',
'OTROB',
'TROBO' ]
Now I have:
[ 'robotr', 'obotr', 'botr', 'otr', 'tr' ]
Where am I going wrong? Here is my code:
function scrollingText(word) {
word = word.toUpperCase();
let arr = [];
for (let i = 0; i < word.length; i++) {
arr.push(word[i] + word.slice(i + 1) + word[0]);
}
return arr;
}
console.log(scrollingText('robot'));
You need to update word in each iteration, and not merely slice the same word repeatedly. Here is my snippet:
function scrollingText(word) {
let arr = [word.toUpperCase()]; // storing original word
let wordLength = word.length;
for (let i = 0; i < wordLength - 1; i++) { // iterating for one less than the string length, in this case, from 0 to 3
word = word.slice(1) + word[0] // <<-- update word in every iteration
arr.push(word.toUpperCase());
}
return arr;
}
console.log(scrollingText('robot'));

Combine each element of an array with the ones after it

I am trying to combine items in an array, with every item below it. It should make a set of the current character and each character below it, and iteratively walk down the array. For example, if I have an array like this:
var myArray = ['A','B','C','D']
I would like an output like this:
AB AC AD BC BD CD
The code I have is getting me close, but I am having a hard time figuring out the rest. Here is what I have so far:
var myArray = ['A', 'B', 'C', 'D']
var sql_parts = []
var string = "";
for (var i = 0; i < myArray.length; i++) {
recurse_function(string, i)
}
console.log(sql_parts)
function recurse_function(string_val, count) {
if ((myArray.length - count) == 0) {
return string_val;
} else {
string_val += myArray[count]
sql_parts.push(string_val)
recurse_function(string_val, count + 1)
}
}
But this produces:
["A", "AB", "ABC", "ABCD", "B", "BC", "BCD", "C", "CD", "D"]
Here is one solution:
Define the recursive function to take the array and an empty list initially to store the combinations
The base condition is when the array is empty or has one element
Otherwise, Remove the first element "start"
Iterate over the array to store its combinations with its following elements
Recur again with array and combinations updated
function recurse_function(array, combinations = []) {
if(array.length <= 1) return combinations;
const start = array.shift();
for(let i = 0; i < array.length; i++) combinations.push(`${start}${array[i]}`);
return recurse_function(array, combinations);
}
console.log( recurse_function(['A','B','C','D']) );
var myArray = ['A','B','C','D']
var sql_parts = []
for(var i =0; i< myArray.length; i++){
var a = myArray[i]
for(var j = i+1; j<myArray.length; j++){
var b=myArray[j]
var c= a+b
sql_parts.push(c)
}
}
I think this is something that you're looking for, it's a function that is very cheap on resources. Its not recursive (why you now would need something like that for this simple scenario)
var myArray = ['A','B','C','D']
let [a, b, iter] = [0, 1, 2]
let result = []
for (;a < myArray.length; a++) {
for (;b < myArray.length; b++) {
result.push(myArray[a]+myArray[b])
}
b = iter++
}
console.log(result)
I don't think you need to recurse in this particular case. You can simply combine the current element with the following ones with flatMap:
['A','B','C','D'].flatMap((x, i, xs) => xs.slice(i+1).map(y => x+y));
//=> ["AB", "AC", "AD", "BC", "BD", "CD"]
var myArray = ['A', 'B', 'C', 'D'];
var result = [];
myArray.forEach((item, index) => {
myArray.forEach((item2, index2) => (index < index2 ? result.push(item + item2) : ''));
});
console.log(result);

Looping through array using splice method infinite loop javascript

When i loop through the array using the splice method, the page just freezes. It looks like i caused an infinite loop. lib.randomInt() works, so that is not the problem.
function() {
return function(string) {
var arr = string.split("")
arr.sort();
for(var i = 0; arr.length;i++){
arr.splice((i+1),0,lib.randomInt(9));
}
var pseudocryptarr = arr.join("");
}
})()("example");
This is from a different file that is placed above the main file in html
var lib = {
factorial: function(num){
function _factorial(num){
if(num === 1){
return 1;
} else {
return num*_factorial(num-1);
}
}
console.log(num+"! = " + _factorial(num));
},
randomInt: function(int,offset){
if(offset == undefined || null || NaN){
offset = 0;
}
return Math.floor(Math.random()*int)+offset;
},
display: function(m, fn){
fn(m);
}
};
You've got to loop in reverse when modifying the array itself to avoid corrupting the loop like this...
for (var i=arr.length-1; i>=0; i--){}
I guess that you wanted to insert a random value after every array element, so that the string "example" would become something like "e5x9a2m4p7l1e3"
There are two issues:
Your for loop has no end condition that will become false. You need to state i < arr.length instead of just arr.length which is always truthy for non-empty arrays.
You add array elements in every iteration, but then also visit them in the next iteration, and from there on you will only be visiting the new inserted values and never get to the next original element that keeps being 1 index away from i. You need to increment i once more. For that you can use ++i instead if i+1 as the splice argument.
So your loop should be:
for(var i = 0; i < arr.length; i++) {
arr.splice(++i,0,lib.randomInt(9));
}
const lib = { randomInt: n => Math.floor(Math.random()*n) };
(function() {
return function(string) {
var arr = string.split("")
arr.sort();
for(var i = 0; i < arr.length; i++) {
arr.splice(++i,0,lib.randomInt(9));
}
var pseudocryptarr = arr.join("");
console.log(pseudocryptarr);
}
})()("example");
Or to save an addition:
for(var i = 1; i <= arr.length; i+=2) {
arr.splice(i,0,lib.randomInt(9));
}
const lib = { randomInt: n => Math.floor(Math.random()*n) };
(function() {
return function(string) {
var arr = string.split("")
arr.sort();
for(var i = 1; i <= arr.length; i+=2) {
arr.splice(i,0,lib.randomInt(9));
}
var pseudocryptarr = arr.join("");
console.log(pseudocryptarr);
}
})()("example");
I fixed it. I wanted after each character for there to be a number. Using the pre-looped array length and doubling it while iterating twice, means that the splice adds the number after the new number element and then the character.
Edit: My typo was the problem. I didnt even have to use len, just iterate by 2.
for(var i = 0;i < arr.length;i+=2){
arr.splice((i+1),0,lib.randomInt(9));
}
(function() {
return function(string) {
var arr = string.split("")
arr.sort();
var len = arr.length
for(var i = 0;i < len*2;i+=2){
arr.splice((i+1),0,lib.randomInt(9));
}
var pseudocryptarr = arr.join("");
console.log(pseudocryptarr);
}
})()("example");
Edit: user4723924 method is better:
(function() {
return function(string) {
var arr = string.split("")
arr.sort();
for(var i = arr.length;i >= 0;i--){
arr.splice((i+1),0,lib.randomInt(9));
}
var pseudocryptarr = arr.join("");
console.log(pseudocryptarr);
}
})()("example");

Concatenating an array with itself

I'm trying to implement Array.repeat, so
[3].repeat(4) // yields
=> [3, 3, 3, 3]
... and is driving me crazy.
Tried with this:
Array::repeat = (num)->
array = new Array
for n in [0..num]
array.concat(this)
array
But [3].repeat(x) always returns []. Where I'm screwing it up? Or is there a better approach do this?
Final result:
Array::repeat = (num)->
array = new Array
return array if num < 1
for n in [1..num]
array = array.concat(this)
array
['a'].repeat(5)
=> ['a', 'a', 'a', 'a', 'a']
array.concat returns a new array and does not modify the existing one.
You need to write
array = array.concat(dup)
Alternatively, you can use push(), which does modify the original array:
array.push.apply(array, dup)
This is rather simple:
function repeat(array, n){
var out = [];
for(var i = 0; i < n; i++) {
out = out.concat(array);
}
return out;
}
Or prototyping:
Array.prototype.repeat = function(n){
var out = [];
    for(var i = 0; i < n; i++) {
out = out.concat(this);
}
return out;
}
That's native JS, not sure how you'd do that in CoffeeScript.
I think this is how function should look like:
Array.prototype.repeat = function(count) {
if(count==null||1*count!=count) //check for cerrect count
return this.valueOf();
var length = this.length; //Length
var return = this.valueOf(); //0 repats equals in the same array
for(var i=0; i<count; i++) { //Repeating the count
for(var j=0; j<length; j++) {
return.push(this[j]);
}
}
}

Categories

Resources