Seeking assistance with building nested array in JavaScript - javascript

This is a question that has come up a few times on here in the past but I just can't get my head around it.
This is how my output is looking at the moment:
0 "affiliate_hoover_plugin_options[1][radioName]:mac"
1 "checked:true"
2 "affiliate_hoover_plugin_options[2][radioName]:pc"
3 "checked:false"
4 "affiliate_hoover_plugin...ons[3][radioName]:linux"
5 "checked:false"
And this is how I want it to look:
1: "affiliate_hoover_plugin_options[1][radioName]:mac", "checked:true"
2: "affiliate_hoover_plugin_options[2][radioName]:pc", "checked:false"
3: "affiliate_hoover_plugin...ons[3][radioName]:linux", "checked:false"
This is how my code looks:
var newForm = [];
for (var i = 1; i < oldForm.length; i += 1) {
newForm.push(oldForm[i].name + ":" + oldForm[i].value);
if (oldForm[i].type === "radio") {
newForm.push("checked" + ":" + oldForm[i].checked);
}
}
console.log(OnewForm);
Now I'm going to have put an extra for loop in there aren't are, which is where I'm confusing myself.
I think I just need a break

like this?
var newForm = [];
for (var i = 1; i < oldForm.length; i += 1) {
if (oldForm[i].type === "radio") {
newForm.push( [ oldForm[i].name + ":" + oldForm[i].value, "checked:" + oldForm[i].checked ] );
} else {
newForm.push( [ oldForm[i].name + ":" + oldForm[i].value ]);
}
}

var newForm = [];
for (var i = 0; i < oldForm.length; i++) {
var array = [];
array.push(oldForm[i].name + ":" + oldForm[i].value);
array.push("checked" + ":" + oldForm[i].checked);
newForm.push(array);
}
console.log(newForm);
might work

Related

Javascript Fib series test case fails

I am trying to complete this assignment for the Javascript Fibonacci series. The logic works for input 5 and 6. But the test case for 8 fails.
function fibonacciSequence(input) {
//Type your code here.
var i = 0;
var fib = [];
fib[0] = 0;
fib[1] = 1;
var out ="0"+ "" +"1";
for (i = 2; i <=input; i++) {
fib[i] = fib[i-2] + fib[i-1];
out = out+ ""+ fib[i];
console.log("i is" + i + " out is" + out);
}
return out;
}
I cannot figure out what is going wrong..
It seems like things are just getting messed up with how you are adding the items to the string. Since there is no space between out + "" + fib[i], I think that would be messing with the formatting. Once i had spaces it seems to work fine, a double digit number wouldnt mess with a string like that.
function fibonacciSequence(input) {
var fib = [];
fib[0] = 0;
fib[1] = 1;
let out = ""
out+= ` ${0} `
out+= `${1}`
for (let i=2; i <=input; i++) {
fib[i] = fib[i-2] + fib[i-1];
out+= ` ${fib[i]}`
}
return out;
}
You are comparing the input (which it seems like this is maybe the number you want to stop at) to i which (plus or minus a bit) is the number of numbers in the list. You probably want to be comparing fib[i], or something like it to input to decide whether to terminate the loop.
Edit: If that's wrong and you do want input to be the number of numbers in the list, then you could just join fib at the end:
function fibonacciSequence(input) {
//Type your code here.
var i = 0;
var fib = [];
fib[0] = 0;
fib[1] = 1;
//var out ="0"+ "" +"1";
for (i = 2; i <=input; i++) {
fib[i] = fib[i-2] + fib[i-1];
//out = out+ ""+ fib[i];
//console.log("i is" + i + " out is" + out);
}
return fib.join(' ');
}
for(let j = 0; j < 9; j++)
console.log('input: ' + j + ' :: ', fibonacciSequence(j));
Unless ... I've got the wrong end of the stick and #Grant Herman's answer already does what you want?

Need to make a list of the outstanding GPA’s from the array Im making (GPA’s over 3.4). Prefer traditional loop solution over some ES6 function

I need help with getting a list of GPAs over 3.4. I was able to sort largest to smallest, average, and get min and max GPAs utilizing traditional approaches (not ES6).
<div id ="out"></div>
<script>
var gpas = [];
var thegpas = " ";
var total = 0
while (thegpas != "XXX")
{
thegpas = prompt("Enter gpas or XXX to Stop");
if(thegpas != "XXX"){
gpas.push(thegpas);
} else {
break;
}
}
for(var x = 0; x < gpas.length; x++)
{
a = gpas.sort((a,b)=>b-a);
total=total + parseFloat(gpas[x]);
b = total/gpas.length //parseFloat(total)/length;
var max = gpas[0];
var min = gpas[0];
for(var i = 1; i < gpas.length; ++i) {
if (gpas[i]>max) {
max = parseFloat(gpas[i]);
}
else if (gpas[i] < min) {
min = parseFloat(gpas[i]);
}
}
//need help with this part
//outstandingGPAs=0;
outstandingGPAs = [];
cutoff = 3.4;
if (gpas[x]>cutoff){
outstandingGPAs.push(parseFloat(gpas[x]));
}
out= "Largest to smallest " + a + "<br/>" + "GPAs average: " + b + "<br/>" + " Max and Min: " + max + ", " + min + "<br/>" + "Outstanding GPAs (greather than 3.4): " + outstandingGPAs ;
// alert(gpas[x]);
}
document.getElementById('out').innerHTML=out;
Current Output:
Best way to output a (not very long) array is the join function.
In your output, you should use:
out = "<whatever you put>" + outstandingGPAs.join();
Check this link for more explanation of the join function.
Since you are already looping over your gpas array you could save those that are over 3.4 while you do that.
You would do that within your existing loop, not afterwards.
const cutoff = 3.4;
let outstandingGPAs = [];
// ...
for (var i = 1; i < gpas.length; ++i) {
if (gpas[i]>max) {
max = parseFloat(gpas[i]);
}
else if (gpas[i] < min) {
min = parseFloat(gpas[i]);
}
// added to the existing loop
if (gpas[i] > cutoff) {
outstandingGPAs.push(gpas[i]);
}
}
The outer loop should not be there, as you just redo the same operation over and over again.
As you only push at most one value in outstandingGPAs after you have set it to the empty array, that result will be wrong.
There are several other similar issues going on...
Also, getting input with prompt is really not user-friendly. The way to do this, is using an input element, and let the user type all values freely, and go back and correct whenever they want, and when they are happy with it, they can press a button so the code can run on it.
Here is how that looks:
var calcButton = document.getElementById("calc");
var gpasInput = document.getElementById("gpas");
var outDiv = document.getElementById('out');
calcButton.addEventListener("click", function () {
var min = Infinity,
max = -Infinity,
total = 0,
gpas = [],
outstandingGPAs = [];
// Collect the input as an array of strings with number-related characters
var inputStrings = gpasInput.value.match(/-?\d+(\.\d+)?/g);
for (var i = 0; i < inputStrings.length; i++) {
var num = parseFloat(inputStrings[i]);
gpas.push(num);
if (num > 3.4) {
outstandingGPAs.push(num);
}
if (num < min) {
min = num;
}
if (num > max) {
max = num;
}
total += num;
}
var average = total / gpas.length;
gpas.sort((a, b) => b - a);
// lets also sort the outstanding GPAs
outstandingGPAs.sort((a, b) => b - a);
outDiv.innerHTML = "Largest to smallest " + gpas.join(", ") + "<br>"
+ "GPAs average: " + average + "<br>"
+ "Max and Min: " + max + ", " + min + "<br>"
+ "Outstanding GPAs (greather than 3.4): " + outstandingGPAs.join(", ");
});
Enter gpas values: <input id="gpas">
<button id="calc">Calculate</button><br>
<div id ="out"></div>
Here:
let theGpas = "";
let gpaArr = [];
while(theGpas != "XXX"){
theGpas = prompt("Enter GPAs. Enter XXX to stop.");
if(theGpas != "XXX"){
gpaArr.push(theGpas);
}
}
gpaArr = gpaArr.sort();
document.write("Largest to Smallest: "+gpaArr.join(",")+"<br/>");
function average(array){
var totalSum = 0;
for(var n in array){
totalSum += array[n];
}
return totalSum/array.length;
}
function moreThanArray(array, comparison){
var returnArr = [];
for(var z in array){
if(array[z]>comparison){
returnArr[returnArr.length] = array[z];
}
}
return returnArr;
}
const averageOf = average(gpaArr);
document.write("GPAs average: "+averageOf+"<br/>");
document.write("Max and Min: "+gpaArr[gpaArr.length-1]+", "+gpaArr[0]);
document.write("<br/>"+"Outstanding GPAs (greater than 3.4): "+moreThanArray(gpaArr, 3.4).join(","));

Calling concatenated variables in Javascript

Is there a way to include variables in each iteration of a javascript loop? For example if I put this code into a loop
if (e1) {item_text += '{id:"' + id[1] + '",lvl:' + e1lvl + '},<wbr>'}
if (e2) {item_text += '{id:"' + id[2] + '",lvl:' + e2lvl + '},<wbr>'} // etc
and do something like
for (n = 0; n < id.length; n++) {
if (e/*concat var e w/var n?*/) {
item_text += '{id:"' + id[1] + '",lvl:' + e/*concat var e w/var n?*/lvl + '},<wbr>'
}
}
Is there a way to change the number in the var names (e1 -> e2 etc) each iteration or do i just have to keep it the long way and write everything out on its own line?
It would be possible, though highly not recommended, to use eval to come up with the variable name:
const e1lvl1 = 'foo';
const e2lvl1 = 'bar';
for (let i = 1; i < 3; i++) {
console.log(eval('e' + i + 'lvl1'));
}
But it would be better to fix your script's architecture so that this isn't necessary: put each e#lvl into an array, and then access the appropriate index of the array on each iteration:
const elvl = [
'foo',
'bar'
];
let item_text = '';
for (let i = 0; i < elvl.length; i++) {
item_text += 'lvl: ' + elvl[i] + '\n';
}
console.log(item_text);
Arrays/Objects exist in javascript for a reason! Simplify your code. There is no reason to have e1, e1l, e2... as variables. Add them to an object and access them by key, or add them to an array, and loop through them. There are many javascript functions as well that will allow you to ensure all elements match a certain condition.
function submit() {
var e = {};
var idx = 28;
for (var i = 0; i <= 24; i++) {
e[i] = {};
e[i].key = document.getElementById(`ench${i}`).checked
e[i].value = $.trim(form.elements[idx].value)
idx += 2;
}
// Check condition
if (Object.values(e).some(e => e.key)) {
//One of the checked items was true
}
}
I would agree that you should change your code to use arrays.
To answer your question though, since your e1 and e1lvl variables look to be global scope, you can access them like this
window["e1"]
window["e1lvl"]
Give this a try
for (n = 0; n < id.length; n++) {
if (window["e" + n]) {
item_text += '{id:"' + id[n] + '",lvl:' + window["e" + n + "lvl"] + '},<wbr>';
}
}

Getting all variables with a name

I'd like to display each variable created by
while (i < document.getElementById("box").value.split("").length) {
this["numb_" + i] = document.getElementById("box").value.split("")[i];
i++;
};
to display in document.getElementById("text").innerHTML to make a result that looks like this in the webpage :foo + variable1created + foo + variable2created + foo + variable3created etc...The whole goal is to take numbers from the text box, split the digits, and display each digit separately (means with other text between), all automatically. End result text is loopable.
Here is my codepen so you can take a look at it (I made the code very simple :) here http://codepen.io/ninivert/pen/bdEYqx
I guess this is what you are looking for
var i = 0;
var num = this["numb_" + i];
while (!!num) {
process(num);
num = this["numb_" + (++i)];
};
Thanks to Katerina Tort for the help !
Updated the codepen to contain answer.
http://codepen.io/ninivert/pen/bdEYqx
function myFunction() {
var i = 0;
while (i < document.getElementById("box").value.split("").length) {
this["numb_" + i] = document.getElementById("box").value.split("")[i];
i++;
};
fillText();
}
function fillText(){
var i = 0;
var num = this["numb_" + i];
var result = '';
while (!!num) {
console.log(num)
result += process(num);
num = this["numb_" + (++i)];
}
document.getElementById("text").innerHTML = result;
}
function process(num) {
return 'foo' + num;
}

Each key value, join values inside loop

So i have a string, and I'm trying to join the content; if the val length is less than 10 chars, join it with the next value. But when i try this code, it joins with the same val instead of the next one.
//Set the regex.
myregex = /(<p>.*?<\/p>)/g;
//Variable string.
content = Example: <p>Hello</p><p>This is my test content</p><p>etc</p>
$(content.match(myregex)).each(function (key, val) {
var test = $(val).text();
if (test.length < 10) {
var n = val.concat(val);
$('#mydiv').append('<div>' + n + '</div>');
} else {
$('#mydiv').append('<div>' + val + '</div>');
}
})
This line here: val.concat(val), is indeed duplicating your content. What you need to do is grab the next value from the regex instead of the current one. Something like the following should work.
var matches = content.match(myregex),
myDiv = $('#mydiv');
for (var i = 0, len = matches.length; i < len; i++){
if (i + 1 < len && matches[i].length < 10){
myDiv.append('<div>' + matches[i].concat(matches[i+1]) + '</div>');
i += 1;
}
else myDiv.append('<div>' + matches[i] + '</div>');
}
val and val are the same thing, so of course val.concat(val) will duplicate it.
If you want to use $.each, I think it might be better to join with the previous value, because you don't know what the next one will be yet.
var previous = [];
$(content.match(myregex)).each(function (key, val) {
var test = $(val).text();
if (test.length < 10) {
previous = val;
} else {
if(previous.length) {
val = previous.concat(val);
}
$('#mydiv').append('<div>' + val + '</div>');
previous = [];
}
});

Categories

Resources