JavaString loop through string and break string into sub strings - javascript

I want to loop through set of strings and break them into sub strings by removing two characters and storing them into an array.
lets say two stings are returned, the number of characters will always be multiple of 2.
AADDFFCC
GGDD
The first string will give me AADDFF,AADD,AA
The second string will give me GG.
i want to store all sub string into a single array.
So based upon above example i should end up with.
subString = ["AADDFF","AADD","AA","GG"]
This is my incomplete attempt.
var StringArray = ["AADDFFCC","GGDD"] //this could be indefinite length
var subString = [];
var StringArrayLength = StringArray.length;
var loopCurrentString;
var loopCurrentSubString
for (var i = 0; i < StringArrayLength; i += 2) {
loopCurrentString = StringArray[i];
loopCurrentSubString = loopCurrentString.substring(0, loopCurrentString.length - 2);
}

for (var i = 0; i < StringArrayLength; i ++) {
//get element
loopCurrentString = StringArray[i];
//add substrings in the array
while(loopCurrentString.length>2){
loopCurrentSubString = loopCurrentString.substring(0, loopCurrentString.length - 2);
substring.push(loopCurrentSubString);
}
}

Here is an implementation with nested for loops:
const data = ["AADDFFCC", "GGDD"]
const endResult = []
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < data[i].length; j += 2) {
if (j != 0)
endResult.push(data[i].slice(0, data[i].length - j))
}
}
console.log(endResult)
You could do this by using reduceRight to chunk the array into the desired pieces starting from the right side:
const data = ["AADDFFCC","GGDD"]
const chunkBy = (arr, by=2) => [...arr].reduceRight((r,c,i,a) =>
((((a.length-1) - i)%by == 0 && a.length-1 != i) ?
r.push(a.slice(0, i+1).reduce((r,c) => `${r}${c}`)) :
0, r),[])
console.log(data.reduce((r,c) => [...chunkBy(r), ...chunkBy(c)]))
And on the end stitch them together via ES6 spread operator.

Related

Javascript for loop not iterating across array or values in an if statement not updating as planned

Trying to return the highest 5 digit number out of any given number i.e 34858299999234
will return 99999
I think I have it narrowed down to the for loop not iterating the array properly OR the values for 'hold1' and 'hold2' are not updating.
function solution(digits){
//Convert string to array to iterate through
let arr = digits.split("");
let final = 0;
//iterate through the array in 5 sequence steps
for(let i = 0; i < arr.length-1; i++){
let hold1 = arr[i] + arr[i+1] + arr[i+2] + arr[i+3] + arr[i+4];
hold1 = parseInt(hold1,10); //converting string to int so if statement functions correctly
let hold2 = arr[i+1] + arr[i+2]+ arr[i+3] + arr[i+4] + arr[i+5];
hold2 = parseInt(hold2,10);
if(hold1 >= hold2){
final = hold1;
}else{
final = hold2;
}
return final;
}
}
if you need a five digits result you need to change the for loop in something like this:
for (let i = 0; i < arr.length - 5; i++) {
Otherwise you will generate results shorter than 5 digits.
Also, I think you are missing the Math.max method that will compare two numbers to return the bigger one.
I rewrote your function this way:
function solution(digits) {
let op = 0;
let length = 5;
let stringDigits = String(digits); /// <-- I use string instead of array
if (stringDigits.length <= length) {
return digits; /// <-- If input is shorter than 5 digits
}
for (let i = 0; i < stringDigits.length - length; i++) {
const fiveDigitsValue = stringDigits.substr(i, length);
op = Math.max(op, Number(fiveDigitsValue));
}
return op;
}

How can I know if the characters of a string repeat themselves the same amount of times when they have a wildcard built-in?

examples:
testing("xyzy**") should be true.
testing("xyzy*") should be false.
Reasoning:
In the first case, it is true because one * can behave as a x and the other a z, so all characteres would of the same amount of y.
In the second case there wouldn't be the same amount of characters repeating itself, cause there is only one *, so it is false.
Here is what I have up until now:
const testing = string => {
var array = []; //array with each character without repeating
var array_R = []; //array with the value the value that each character repeats itself
var array_C = 0; //counter for the size of "array"
//getting the character without repeating
for (var i = 0; i < string.length; i++) {
if (!array.includes(string.charAt(i))) {
array[array_C] = string.charAt(i);
array_R[array_C] = 0;
array_C++;
}
}
//how many each character repeats itself
for (var i = 0; i < array.length; i++) {
for (var j = 0; j < string.length; j++) {
if(array[i] == string.charAt(j)){
array_R[i] = array_R[i] + 1;
}
}
}
}
I really don't know how I can proceed from here.
First count up the number of occurrences of each non-* character into an object or Map. Find the maximum value in that collection, then find the sum of all differences between the maximum value and each value. If the number of asterisks is the same as the sum of differences, the repeat conditions are fulfilled.
You'll also have to consider the case where there are more asterisks left over after all holes are filled in to make the values equal - figure out how many are left over, and see if that evenly divides the number of separate characters.
const testing = (str) => {
const grouped = {};
for (const char of str) {
if (char !== '*') grouped[char] = (grouped[char] || 0) + 1;
}
const values = Object.values(grouped);
const numOfSeparateChars = values.length;
const max = Math.max(...values);
const sum = values.reduce((a, b) => a + b, 0);
const sumOfDifferencesFromMax = max * numOfSeparateChars - sum;
const numberAsterisks = (str.match(/\*/g) || []).length;
const remainingAsterisks = sumOfDifferencesFromMax - numberAsterisks;
// Now all characters have been filled in to make the values even
// eg: 'abcc**' -> 'abccab'
// But there may be more asterisks
// eg: 'abcc*****' -> 'abccaabbc'
return remainingAsterisks % numOfSeparateChars === 0;
};
console.log(testing("xyzy**"));
console.log(testing("xyzy*"));

Loop for isn't getting the right position of the array, Why?

I'm learning JavaScript and I came across the following situation:
My code:
alfabetoMadegues = "jngmclqskrzfvbwpxdht"
var listaLetras = Array.from(alfabetoMadegues);
dicionario_Madegues = {};
for (var i = 0 < listaLetras.length; i++;) {
listaLetras.forEach(element => {
dicionario_Madegues[element] = i;
})
};
If "j" is the first element of the array Why "j" is receiving 2 instead 0?. Why am i getting this result?
The expected result should be:
"j" 0
"n" 1
"g" 2
"m" 3
"c" 4
"l" 5
ES6 Soluce aka ECMA2015 - see compatibility table
As second parameter of Array.forEach you can get the position of the element; as example :
const alfabetoMadegues = 'jngmclqskrzfvbwpxdht';
const listaLetras = Array.from(alfabetoMadegues);
const dicionario_Madegues = {};
listaLetras.forEach((x, xi) => {
dicionario_Madegues[x] = xi;
});
console.log(dicionario_Madegues);
Also, the use of Array.reduce is more appropriate; as example
PS: We use of Spread operator ... and dynamic key naming [x].
const alfabetoMadegues = 'jngmclqskrzfvbwpxdht';
const listaLetras = Array.from(alfabetoMadegues);
const dicionario_Madegues = listaLetras.reduce((tmp, x, xi) => ({
...tmp,
[x]: xi,
}), {});
console.log(dicionario_Madegues);
ES5 Soluce
var alfabetoMadegues = 'jngmclqskrzfvbwpxdht';
var listaLetras = Array.from(alfabetoMadegues);
var dicionario_Madegues = {};
for (var i = 0; i < listaLetras.length; i += 1) {
dicionario_Madegues[listaLetras[i]] = i;
}
console.log(dicionario_Madegues);
You don't want that forEach inside the for. For the output you've described, you want to just remove that and replace it with dicionario_Madegues[listaLetras[i]] = i;.
You also have an error in your for loop. You have:
for (var i = 0 < listaLetras.length; i++;) {
...which will run forever. The initialization and test should be separated with ;:
for (var i = 0; i < listaLetras.length; i++) {
// -----------^^^--------------------------^ (no `;` after `i++`)
Live example:
var alfabetoMadegues = "jngmclqskrzfvbwpxdht";
var listaLetras = Array.from(alfabetoMadegues);
var dicionario_Madegues = {};
for (var i = 0; i < listaLetras.length; i++) {
dicionario_Madegues[listaLetras[i]] = i;
}
console.log(dicionario_Madegues);
Also note the various places I've removed and added ;. It's probably worth reviewing the rules for them.
You are looping two times:
for (var i = 0 < listaLetras.length; i++;) { // HERE
listaLetras.forEach(element => { //HERE
dicionario_Madegues[element] = i;
})
};
So you have to use either the for or the forEach:
alfabetoMadegues = "jngmclqskrzfvbwpxdht"
var listaLetras = Array.from(alfabetoMadegues);
var dicionario_Madegues_CON_FOR = {};
var dicionario_Madegues_CON_FOREACH = {};
for (var i = 0 ; i < listaLetras.length ; i++ ) {
dicionario_Madegues_CON_FOR[listaLetras[i]] = i;
};
listaLetras.forEach((letra, indice) => dicionario_Madegues_CON_FOREACH[letra] = indice);
console.log(dicionario_Madegues_CON_FOR);
console.log(dicionario_Madegues_CON_FOREACH);
There are also sintax errors in your for:
for (var i = 0 < listaLetras.length; i++;)
That should be
for(var i = 0 ; i < listaLetras.length ; i++ )
In addition to the provided answers you also can consider the following approach:
alfabetoMadegues = "jngmclqskrzfvbwpxdht"
var obj = {}
alfabetoMadegues.split('').forEach((element, index) => obj[element] = index)
console.log(obj)
There is a mistake on this line
for (var i = 0 < listaLetras.length; i++;) {
The for construct has three sections:
Initilisation
Condition
Afterthought
Each section is separated with a ;
You've smooshed your condition (i < listaLetras.length) and initialisation together. The afterthought is being left blank.
The correct code would be
for (var i = 0; i < listaLetras.length; i++) {
The reason j is 2 is for two reasons;
On the first pass of the loop i is getting set the the value of i < listaLetras.length - this evaluates to true.
Next the loop runs the comparision (to check whether it should run the body of the loop). The comparision here is .... i++ ! i is true so the comparison passes and then i is incremented.
i's value true is getting implicitly cast to a 1 for the increment.
When we hit the body of the loop it is now 2.
You are also looping two times with the foreach function - setting each value to i every iteration of i that occurs.

Iterating through a number and rearranging in descending

I'm trying to rearrange an input number using a function so that a single number is rearranged into descending order.
For example, 234892 would result in 984322.
This is what I have come up with.
function descendingOrder(n){
var num = '';
for(var i = 0; i <= n.length + 1; i++){ // iterates through the number
for(var j = 9; j >= 0; j--){ // starts at 9 and checks numbers descending
if (j == n[i]){
num.push(n[i]); // checks if j == n[i] and if so, pushes to num
}
i = 0; // sets i back to 0 to rescan the number again
}
}
return num;
}
You can convert number to string, split each character, sort it and join it again:
+(234892 + '').split('').sort((a, b) => a < b).join('');
var ordered = +(234892 + '').split('').sort((a, b) => a < b).join('');
document.getElementById('output').appendChild(document.createTextNode(ordered));
234892 → <span id="output"></span>
Detailed explanation:
var str = 234892 + ''; // convert to string
var parts = str.split(''); // convert to array of characters
// sort
parts.sort(function(a, b) {
return a < b;
});
var finalStr = parts.join(''); // join characters to string
var finalNumber = +finalStr; // convert back to number
console.log(finalNumber); // 984322

Compare two strings in javascript/jquery

In the string below, I want to split the string separated by "|" (which i can do)and would then like to compare the first part and the boolean part of each such string with the same parts of another string.
var str = "Jacobs21]2]0]Ronan]false|Tom]2]0]Joseph]true|Jacobs21]2]0]NAME$$ALL]false|";
In the string above, Jacobs21]2]0]Ronan]false is one string and so on.
I am more interested in the Jacobs21 part of this string and the boolean value appearing at its end which is "false" here.
Now, I want to compare the first and the last part joined as a single string to form Jocobs21false and similarly, for the another string tomtrue and make a comparison and see if there are any similar matches?
var detailsArray = str.split("|");
var res = [];
for (var i = 0; i < detailsArray.length - 1; i++) {
finalArray = detailsArray[i].toString().split("]");
var name = finalArray[0];
var booleanString = finalArray[4];
res[i] = name.concat(booleanString);
}
for (var j = 0; j < res.length - 1; j++) {
if (res[i] == res[i + 1]) {
//do your stuff
}
}

Categories