I have a simple array
var answerAttribute = ['A','B','C','D'];
I have 16 list items, what I'm trying to accomplish is loop through the length of the list and regardless of if the list 2 items or 300. I'd lke to have a data attribute associated with it of A,B, C or D.
Here's what I'm working with:
var questionOption = '';
for(var i = 0; i < quizContent.length; i++) {
questionOption = answerAttribute[i % answerAttribute.length];
console.log(questionOption);
}
When logging this to the console, it logs A, AB, ABC, ABCD, ABCDundefined, and keeps repeating undefined until it's reached the loops conclusion. My question is what am I doing incorrectly so that it only logs one letter per loop.
questionOption += answerAttribute[i]
This statement is short-form for questionOption = questionOption + answerAttribute[i]. It will append the next element to questionOption in every iteration of the loop.
It looks like what you want is probably questionOption = answerAttribute[i]. This will replace the value in questionOption with the new element instead of appending it.
You could simply log only the current value, like this:
var questionOption = '';
for (var i = 0; i < quizContent.length; i++) {
//what is questionOption used for?
questionOption += answerAttribute[i];
console.log(answerAttribute[i]);
}
or if you want questionOption to refer to the current value
questionOption = answerAttribute[i];
console.log(questionOption );
You're looping the quizContent indexes and applying them to the answerAttribute array. I believe what you want is a nested loop...
var quizContent = Array(10); // assume you have 10 quiz questions...
var answerAttribute = ['A','B','C','D'];
for (var i = 0; i < quizContent.length; i++) {
// generate a string for each quiz option
var questionOption = '';
for (var n = 0; n < answerAttribute.length; n++) {
questionOption += answerAttribute[n];
}
quizContent[i] = questionOption;
console.log(questionOption);
}
console.log(quizContent);
Somehow I doubt that the question is actually about the logging, and is actually about the resulting string.
Either way, I'd do this without loops.
var answerAttribute = ['A','B','C','D'];
var quizContent = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1];
var questionOption = answerAttribute
.join("")
.repeat(Math.ceil(quizContent.length / answerAttribute.length))
.slice(0, quizContent.length);
console.log(questionOption);
It just joins the answerAttribute into a string of characters, and repeats that string the number of times that the length of answerAttribute can be divided into quizContent.length (rounded up).
Then the final string is trimmed down to the size of the quizContent to remove any extra content from the rounding up.
Note that this approach assumes a single character per attribute. If not a single, but they're all the same length, it can be adjusted to still work.
Related
I have a function that I have modified to get a string (which consists of zeros and ones only).
The string (timesheetcoldata):
100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000
The string items (the numbers one and zero) will change every time the function is run.
It will always be the same length.
I have made the string above easier to see what I am trying to achieve.
I want to return the first character and then every 24th character (as in the variable colsCount in the function).
so, in the example above, it would return something like: 111111
I then want to convert these characters to numbers (something like [1, 1, 1, 1, 1, 1]).
I then want to sum these number together (so it would return, in the example: 6).
I then want to check if the returned number matches the variable: rowsCount
or true if it does, false if it does not.
My function:
$("#J_timingSubmit").click(function(ev){
var sheetStates = sheet.getSheetStates();
var rowsCount = 6;
var colsCount = 24;
var timesheetrowsdata = "";
var timesheetcoldata = "";
for(var row= 0, rowStates=[]; row<rowsCount; ++row){
rowStates = sheetStates[row];
timesheetrowsdata += rowStates+(row==rowsCount-1?'':',');
}
timesheetcoldata = timesheetrowsdata.replace(/,/g, '');
console.log(timesheetcoldata);
});
Thank you very much to both Rajesh and MauriceNino (and all other contributers).
With their code I was able to come up with the following working function:
$("#J_timingSubmit").click(function(ev){
var sheetStates = sheet.getSheetStates();
var rowsCount = 6;
var timesheetrowsdata = "";
var timesheetcoldata = "";
for(var row= 0, rowStates=[]; row<rowsCount; ++row){
rowStates = sheetStates[row];
timesheetrowsdata += rowStates+(row==rowsCount-1?'':',');
}
timesheetcoldata = timesheetrowsdata.replace(/,/g, '');
var count = 0;
var list = [];
for(var i = 0; i< timesheetcoldata.length; i+=24) {
const num1 = Number(timesheetcoldata.charAt(i));
list.push(num1);
count += num1;
}
let isSameAsRowsCount = count == rowsCount;
console.log('Is Same? ', isSameAsRowsCount);
});
You can always rely on traditional for for such action. Using functional operations can be more readable but will be more time consuming(though not by much).
You can try this simple algo:
Create a list that will hold all numbers and a count variable to hold sum.
Loop over string. As string is fixed, you can set the increment factor to the count(24).
Convert the character at given index and save it in a variable.
Push this variable in list and also compute sum at every interval.
At the end of this loop, you have both values.
var string = '100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000';
var count = 0;
var list = [];
for(var i = 0; i< string.length; i+=24) {
const num1 = Number(string.charAt(i));
list.push(num1);
count += num1;
}
console.log(list, count)
Here is a step by step explanation, on what to do.
Use match() to get every nth char
Use map() to convert your array elements
Use reduce() to sum your array elements
Everything needed to say is included in code comments:
const testData = '100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000';
// Step 1) Create array of numbers from string
const dataArr = testData.match(/.{1,24}/g) // Split on every 24th char
.map(s => Number(s[0])) // Only take the first char as a Number
console.log(dataArr);
// Step 2) Sum array Numbers
let dataSum = dataArr.reduce((a, b) => a + b); // Add up all numbers
console.log(dataSum);
// Step 3) Compare your variables
let rowsCount = 123; // Your Test variable
let isSameAsRowsCount = dataSum == rowsCount;
console.log('Is Same? ', isSameAsRowsCount);
As #Jaromanda mentioned, you can use the following to done this.
const string = '100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000100000000000000000000000';
const value = string.split('').filter((e,i)=> !(i%24)).reduce((acc,cur)=> acc+ (+cur), 0);
console.log(value);
edit: without giving me too much of the answer to how i can do it in a for loop. Could you give me the logic/pseudocode on how to achieve this? the one part i am stuck at is, ok i know that i have to take the first index number and add array.length-1 zeros to it (2 zeros), but i am confused as to when it arrives at the last index, do i put in a if statement in the for loop?
In the below example 459 would be put in an array [4,5,9]
Now I want to take 4 add two zeros to the end because it has two numbers after it in the array
Then I want to take 5 and add one zero to it because there is one number after it in the array.
then 9 would have no zeros added to it because there are no numbers after it.
So final output would be 400,50,9
how can i best achieve this?
var num=459;
var nexint=num.toString().split("");
var finalint=nexint.map(Number);
var nextarr=[];
You need to use string's repeat method.
var num=459;
var a = (""+num).split('').map((c,i,a)=>c+"0".repeat(a.length-i-1))
console.log(a);
Here's another possible solution using a loop.
var num = 459;
var a = ("" + num).split('');
var ar = [];
for (var i = 0; i < a.length; i++) {
var str = a[i];
str += "0".repeat(a.length-i-1);
ar.push(str);
}
console.log(ar);
You could use Array#reduce and Array#map for the values multiplied by 10 and return a new array.
var num = 459,
result = [...num.toString()].reduce((r, a) => r.map(v => 10 * v).concat(+a), []);
console.log(result);
OP asked for a solution using loops in a comment above. Here's one approach with loops:
var num = 459
var numArray = num.toString().split('');
var position = numArray.length - 1;
var finalArray = [];
var i;
var j;
for(i = 0; i < numArray.length; i++) {
finalArray.push(numArray[i]);
for(j = 0; j < position; j++) {
finalArray.push(0);
}
position--;
}
console.log(finalArray);
The general flow
Loop over the original array, and on each pass:
Push the element to the final array
Then push X number of zeros to the final array. X is determined by
the element's position in the original array, so if the original
array has 3 elements, the first element should get 2 zeros after it.
This means X is the original array's length - 1 on the first pass.
Adjust the variable that's tracking the number of zeros to add before
making the next pass in the loop.
This is similar to #OccamsRazor's implementation, but with a slightly different API, and laid out for easier readability:
const toParts = n => String(n)
.split('')
.map((d, i, a) => d.padEnd(a.length - i, '0'))
.map(Number)
console.log(toParts(459))
I am just learning how to program in javascript and I made my first program that "does something". I didn't look for help for any part of the algorithm, just in some parts to find the name of a function I wanted to use. This algorithm seems to work, but it doesnt seem to finish when you have a big list of number, like 10 or more. What yo do you think of it? Is wholly ineficient?
var totNum = Number(prompt("How many numbers you want to compare"));
var unordNum = new Array(totNum);
var ordNum = new Array();
for( var i=1 ; i<= totNum; i++){
unordNum[i] = Number(prompt("Write a new number","0"));
}
while(ordNum.length < totNum){ // I will repeat this process until I order all numbers
for(var i=1; i <=totNum; i++){ //choose a number, lets call it X
if(!(ordNum.indexOf(unordNum[i]) >=0)){ //if it is already ordered, skip it
var z = 0;
for(var j=1; j<=totNum; j++){ //I will compare X against all the others numbers, except
if(!(ordNum.indexOf(unordNum[j]) >= 0)){ //the ones that are already ordered
if( unordNum[i] >= unordNum[j]){ //if X is bigger than a number,
z++; // add 1 to z
}
if(z==totNum-ordNum.length){ // this means X is bigger or equal than all the other numbers
ordNum.push(unordNum[i]); //so write X in the first empty space of the ordered list
}
}
}
}
}
}
document.write(ordNum + "<br>");
You make use of ordNum.indexOf(unordNum[j]) to find if a number is already sorted. This would lead to an infinite loop in case of duplicates. Secondly, you are not really sorting, you would push a number for the first comparison success.
Below is a somewhat similar logic for your sorting.
var totNum = Number(prompt("How many numbers you want to compare"));
var unordNum = new Array(totNum);
var ordNum = new Array();
for( var i=0 ; i< totNum; i++){
unordNum[i] = Number(prompt("Write a new number","0"));
}
for(var i=0; i <totNum; i++){
if(unordNum[i] == undefined) continue; //jump to the next unsorted number
var smallest = unordNum[i]; //initialize smallest to be the first unsorted number
var index = i; //initialize marker index to be set as undefined at last for the number being moved to the sorted array
for(var j=0; j<totNum; j++){ //Comparison loop to find the smallest
if(unordNum[j] != undefined){
smallest = unordNum[j]<smallest ? unordNum[j] : smallest; //Swap if j th number is smaller
index = smallest == unordNum[j] ? j : index; // update index if swapping done
}
}
unordNum[index] = undefined;//mark the number moved
ordNum.push(smallest); // add smallest number to sorted array
i=0; //set outer loop to start from 0 again
}
document.write(ordNum + "<br>");
This would sort by copying the smallest number in the remaining array into a new array. Instead of using ordNum.indexOf(unordNum[j]) as you did, I am marking the sorted element as undefined. Duplicates cannot be sorted in your case. This would leave the new sorted array smaller than the input array and hence an infinite loop. Another thing, why do you use 1 as the starting index? The default index starts from 0 in Javascript as well.
There are far better sorting algorithms but perhaps that is not what you are looking for.
Once you have numbers in array, you can use array.sort()
Suppose I had an array of 5 strings. How can I start a for loop at index 3 and go around and end up at index 2? Let me give an example.
var myArry = ["cool", "gnarly", "rad", "farout", "awesome"];
Would like to start at index 3 ("farout") loop through to end of array ("awesome") then continue looping at index 0 through index 2. Basically beginning an array at some point (other than index 0) and still hit every element in the array.
One way is to loop through the array using an index as normal, and use the modulus operator with your offset, to get a pointer to the correct place in the array:
var myArry = ["cool", "gnarly", "rad", "farout", "awesome"];
var offset = 3;
for( var i=0; i < myArry.length; i++) {
var pointer = (i + offset) % myArry.length;
console.log(myArry[pointer]);
}
So your loop is a standard loop through every element. You take the current position, plus offset, and get the remainder from that divided by the size of the array. Until you reach the end of the array that will just be the same as i + offset. When you reach the end of the array, the remainder will be zero, and go from there.
Here's a fiddle.
Here's what you need:
var start = 3;
for(var z=0;z<myArry.length;++z) {
var idx = (z+start) % myArry.length;
console.log(myArry[idx]);
}
var startAt = 3;
for(var index = 0;index<myArry.length;index++){
console.log(myArry[startAt]);
if(startAt==myArry.length-1){
startAt = -1;
}
startAt++;
}
In my javascript, I've an array named my_array holding values like 0121, 1201, 0012, 0202 etc.
Each individual digit in the string is of importance. So, in the above example, there are 4 values in one string. E.g. 0121 holds 0,1,2,1.
The values can also be longer too. E.g. 01221, 21021 etc. (This is holding 5 values)
I want to know of the easiest and most effective way to do the following:
Add the first digits of all the strings in the array my_array. E.g. 0+1+0+0 in the above example
Add the second digits (e.g. 1+2+0+2) and so on.
I can loop through the array and split the values, then
for(i=0; i<my_array.length; i++){
var another_array = my_array[i].split();
//Getting too complicated?
}
How can I do it effectively? Someone please guide me.
Something like this
var myArray = ["0121", "1201", "0012", "0202"];
var firstValSum = 0;
for(var i = 0; i < myArray.length; i++) {
var firstVal = myArray[i].split("");
firstValSum += parseInt(firstVal[0], 10);
}
console.log(firstValSum); //1
This could be wrapped into a function which takes parameters to make it dynamic. i.e pass in the array and which part of the string you want to add together.
EDIT - This is a neater way of achieving what you want - this code outputs the computed values in an array as you specified.
var myArray = ["0121", "1201", "0012", "0202"];
var newArr = [];
for(var i = 0; i < myArray.length; i++) {
var vals = myArray[i].split("");
for(var x = 0; x < vals.length; x++) {
var thisVal = parseInt(vals[x], 10);
( newArr[x] !== undefined ) ? newArr[x] = newArr[x] += thisVal : newArr.push(thisVal);
}
}
console.log(newArr); //[1, 5, 3, 6];
Fiddle here
var resultArray = new Array(); // This array will contain the sum.
var lengthEachString = my_array[0].length;
for(j=0; j<lengthEachString ; j++){ // if each element contains 4 elements then loop for 4 times.
for(i=0; i<my_array.length; i++){ // loop through each element and add the respective position digit.
var resultArray[j] = parseInt( my_array[i].charAt(j) ); // charAt function is used to get the nth position digit.
}
}