Dynamic, multidimensional array in javascript - counting up not working - javascript

I need a 3 dimensional array to count up - it needs to grow dynamically. It consists of index, string1 and string2.
This outputs exactly, what I want (for a single loop, since the array is just hardcoded to index 0)
var otr_entries=[[0,"",""]];
var otr_entries_count=0;
some_working_for_loop()
{
if(is_important_value_to_save())
{
//otr_entries_count=otr_entries_count+1;
otr_entries[otr_entries_count][1]=xx[i].previousElementSibling.innerHTML;
otr_entries[otr_entries_count][2]=xx[i].innerHTML;
window.alert(otr_entries[otr_entries_count][1]); // Expected output
window.alert(otr_entries[otr_entries_count][2]); // Expected output
}
}
but when I replace otr_entries[0][2] with otr_entries[otr_entries_count][2] the script suddenly fails, if the count is not 0. That means, that the array is not just growing. So how can this be archived?
var otr_entries=[[0,"",""]];
var otr_entries_count=0;
just_some_perfectly_working_for_loop(;;)
{
if(is_important_value_to_save())
{
otr_entries_count=otr_entries_count+1; // Counting up breaks the code
otr_entries[otr_entries_count][1]=xx[i].previousElementSibling.innerHTML;
otr_entries[otr_entries_count][2]=xx[i].innerHTML;
window.alert(otr_entries[otr_entries_count][1]); // No output, script totally stops
window.alert(otr_entries[otr_entries_count][2]); // No output, script totally stops
}
}
EDIT:
This is my solution, thanks to peters help. Works perfectly fine.
var otr_entries=[];
var otr_entries_count=-1;
some_working_for_loop()
{
if(is_important_value_to_save())
{
otr_entries_count=otr_entries_count+1;
otr_entries.push(otr_entries_count,xx[i].previousElementSibling.innerHTML,xx[i].innerHTML)
window.alert(otr_entries[otr_entries_count][1]); // Expected output
window.alert(otr_entries[otr_entries_count][2]); // Expected output
}
}

If in the loop you’re trying to add to the array you need to do otr_entries.push([count,"something","something2"]).
Also, if you’re adding to the array you shouldn’t be using that same array as your loop control.

You're just incrementing the counter before you add new item in the array. The solution is to move the counter incrementing line at the end:
This worked for me
const otr_entries=[[0,"",""]];
const otr_entries_count=0;
for(const entry of otr_entries) {
// condition
if(true) {
otr_entries[otr_entries_count][1]='something';
otr_entries[otr_entries_count][2]='something else'
window.alert(otr_entries[otr_entries_count][1]);
window.alert(otr_entries[otr_entries_count][2]);
otr_entries_count+=1;
}
}

Related

How do I change a single quote of an array.element (that is inside an object) into a double quote without creating a new array?

I was told to try and use a certain code for one of the problems I solved a while ago. I'm trying to figure it out but am coming up with nada.
Using replace(), map() etc..
This is all supposed to be done using replit and not changing the whole array as part of the 'For Fun' challenge.
const products = [
{
priceInCents: 3995,
},
{
priceInCents: 2500,
},
{
priceInCents: 8900,
},
{
priceInCents: 12500,
},
];
/* Now trying to use:
products[i].priceInDollars = $${(products[i].priceInCents * .01).toFixed(2)}
*/
/*
New
Code
*/
function addPriceInDollarsKeyToProducts(pricey)
{ for (let i = 0; i < products.length; i++)
{ for (let product = products[i];
product.priceInDollars = `$${(product.priceInCents * .01).toFixed(2)}`; )
break;
}
}
addPriceInDollarsKeyToProducts();
console.log(products)
Running this snippet btw makes it seem like it's okay.
For example: I want products[0].priceInDollars to be "$39.95",
but instead I get '$39.95',
Snippet runs it as "$39.95"
I'm not supposed to recreate the whole entire array.
If the code doesn't match the double quote requirements I get TypeError: Cannot read property '0' of undefined
edited for clarification purposes
Alright, a friend caught the problem.
I never reinserted my return like a dumb dumb.
Here I was going crazy trying to make a '"$39.95"' into a "$39.95" via replace(), map(), creating a replace function and what not when it was simply that I needed to add
return products;
at the end between the ending }

For loop a number to create buttons inside template literal

Getting a bit stuck with this one.
I'm looping through an object (dataLayer.Tests) and I'm displaying the values of my content, in a DIV. Here's an example of how this object looks:
I'm doing this by looping through my object with forEach. (And in this example, I'm just console.logging my result result3).
The problem I'm having, is that within my forEach, I want to display create/display buttons, depending on what the number is in the totalVariants key/value.
So for example, if the totalVariants === 2, I want to create 2 buttons. If it is one, I want to create 1 button.
I know I need to for loop through this particular value, but I'm not sure how to do this, within a template literal.
Here's my code.
dataLayer.Tests.forEach((element, index, array) => {
let result3 = '';
let numberOfVariants = element.totalVariants;
if (numberOfVariants >= 1) {
for (i = 0; i < numberOfVariants; i++) {
console.log("The number is ", i + 1);
}
result3 += `
<div class="CRO-variant-result">
<p>Date Launched: ${element.date}</p>
<p>Test ID: ${element.id}</p>
<p>Test Description: ${element.name}</p>
<p>Variant Active: ${element.variant}</p>
<p>Total Variants: ${element.totalVariants}</p>
${(function () {
for (i = 0; i < element.totalVariants; i++) {
return `<button>${i}</button>`
}
})()}
</div>
`
console.log("result3", result3);
};
});
I've seen solutions which include .map and object.keys, but this doesn't seem to work/return anything. (Probably as I just need to loop through a number and not array etc.
Any ideas/pointers, would be appreciated.
Basically, I'm not sure how to loop through a number, within a template literal and return x number of elements.
Thanks,
Reena
numberOfVariants is an number, not an object, so one way you could do this is create a new incrementing array of that length (Array.from(Array(numberOfVariants).keys()) does this nicely) and then map over that array as you're doing.
${Array.from(Array(numberOfVariants).keys()).map(i => (
`<button value="${i}">${i}</button>`
)).join('')}
I'm not quite sure what you want to appear inside the button (maybe the integer of the current number as you increment)?

Nested loop (FOR) with IF statement inside 2nd for print just one result

Basically I have 2 arrays, one with some code and another with codes and relative description, what I need to do is match the codes and print the description but my code (apparently) stops at the first loop of the inner FOR (I've attaches a screenshot to understand better).
If I remove the IF statement from the code it prints the counters of the 2 for as it should be.
for (x=0; x<causeoferrorlength; x++)
{
document.getElementById("mdataresult").innerHTML += "x "+causeoferrorsplit[x]+"</br>";
for(k=0; k<78; k++)
{
if ( causeoferrorsplit[x] === gbrucausesoferror[k][0] )
{
document.getElementById("mdataresult").innerHTML += "k "+gbrucausesoferror[k][0]+"</br>";
}
}
}
I have no errors from the console but it isn't printing as expected.
This is probably better handled in a declarative way versus imperative. It will be shorter and easier to reason about.
Given you're using two arrays, and that the codes in the first array will always be found somewhere in the second array:
let causes = ["001", "003", "005"];
let codes = [
["001","Earthquake"],
["002","Sunspots"],
["003","User Error"],
["004","Snakes"],
["005","Black Magic"]
];
let results = causes.map( cause => codes[ codes.findIndex( code => code[0] === cause ) ][1] );
console.log(results); // ["Earthquake", "User Error", "Black Magic"]
What's happening here? We're mapping the array of potential causes of error (the first array) to a list of descriptions taken from the second array.
Array.map takes a function that is invoked once with each array member. We'll call that member 'cause'.
Array.findIndex takes a function that is invoked once for each array member. We'll call that member 'code'.
For each 'cause' in causes we find the index in codes where the first array value is equal to the cause, then return the second array value, the description.
If you have the ability to change the second array to an object, then this gets way simpler:
let causes = ["001", "003", "005"];
let codes = {
"001":"Earthquake",
"002":"Sunspots",
"003":"User Error",
"004":"Snakes",
"005":"Black Magic"
};
let results = causes.map( cause => codes[cause] );
console.log(results); // ["Earthquake", "User Error", "Black Magic"]

I'm trying to use jquery to create a div containing columns but I can't get my array to format correctly

I have an array that contains dates. and for some reason I can't get it to show on my screen I've been debugging for a few days now and I've tracked it down to a single line, but the line has worked before and I can't figure out what the issue might be.
The array looks like this:
var selectItems =
[ "05-26-2017", "06-02-2017", "06-09-2017",
"06-16-2017", "06-23-2017", "06-30-2017", "07-07-2017", "07-14-2017",
"07-21-2017", "07-28-2017"...];
It's passed as an argument from another function, but that's how it's showing in console.log().
I might be going about this the wrong way, maybe even a lot further around then I need to but this is what I've come up with:
1. function setTHead(selectItems) {
2 var formatString;
3. for (var x = 0; x < 12; x++) {
4. formatString = selectItems[x].replace(/[^0-9/-]/g, "").toString();
5. console.log(selectItems);
6. $('#datTab').append("<div id='col" + x + "' class='column'>'" + formatString + "'</div>");
7. }
8. }
the array up top is what's showing from the console.log 5 lines down.
the sixth line is what is seeming to give me issues. Nothing is put on the page at all.
I'm getting a console error saying:
jQuery.Deferred exception: selectItems is undefined setTHead#http://localhost/mySite/script.js:136:9
startUp2#http://localhost/mySite/script.js:146:5
#http://localhost/mySite/table.php:19:9
mightThrow#http://localhost/mySite/lib/jquery.js:3586:52
resolve/</process<#http://localhost/mySite/lib/jquery.js:3654:49
setTimeout handler*resolve/<#http://localhost/mySite/lib/jquery.js:3692:37
fire#http://localhost/mySite/lib/jquery.js:3320:30
fireWith#http://localhost/mySite/lib/jquery.js:3450:29
fire#http://localhost/mySite/lib/jquery.js:3458:21
fire#http://localhost/mySite/lib/jquery.js:3320:30
fireWith#http://localhost/mySite/lib/jquery.js:3450:29
ready#http://localhost/mySite/lib/jquery.js:3923:13
completed#http://localhost/mySite/lib/jquery.js:3933:9
EventListener.handleEvent*#http://localhost/mySite/lib/jquery.js:3949:9
#http://localhost/mySite/lib/jquery.js:39:9
#http://localhost/mySite/lib/jquery.js:17:3
undefined
followed by:
TypeError: selectItems is undefined
and thats pointing to line 6.
if anyone has any advice I would be very much appreciative. Thank you in advance.
EDIT: A little more code:
function startTblView(defSel) {
if (defSel === true) {
setCookie('defSel', true, 7);
} else{
setCookie('defSel', false, 7);
}
saveSelected();
window.open('table.php', '_self');
defSel = getCookie('defSel');
if (defSel) {
selectItems = getDefDates();
}else {
selectItems = reGetSelected();
}
setTHead(selectItems);
}
defSel, is a boolean passed from my last page stating whether I'm doing a default view or a custom view, the custom view is passed from saveSelected();
saveSelected is a function for just saving the selected global value as a cookie so I can pull it out on the next page.
getDefDates pulls the default values for the array
reGetSelected, gets the selected array from the cookie.
I apologize for wonky naming conventions. I'm the only one working on this site and I'm just making sure the names don't overlap.
You can do this :
HTML code
<div id="datTab"></div>
JS code
var selectItems =
[ "05-26-2017", "06-02-2017", "06-09-2017",
"06-16-2017", "06-23-2017", "06-30-2017", "07-07-2017", "07-14-2017",
"07-21-2017", "07-28-2017"];
function setTHead(selectItems) {
var formatString;
$.each( selectItems, function( index, value ){
formatString = value.replace(/[^0-9/-]/g, "").toString();
$('#datTab').append("<div id='col" + index + "' class='column'>'" + value + "'</div>");
});
};
You can use $.each, its better than 'for' with javascript.
The .each() method is designed to make DOM looping constructs concise
and less error-prone. When called it iterates over the DOM elements
that are part of the jQuery object. Each time the callback runs, it is
passed the current loop iteration, beginning from 0. More importantly,
the callback is fired in the context of the current DOM element, so
the keyword this refers to the element.
I did a JsFiddle
Here.

Check for prime in a list using sieve of Eratosthenes

I have an array as an input and i want to print the prime numbers that exist in that list. I was able to do that using trial division method. But I am struck at a point while trying to do the same thing using sieve of Eratosthenes method.
I tried it with below code, but got confused on how to compare the end result array with my input array list and return only those values that matches the input list. ( Detailed answer would be helpful as am a beginner in javascript).
var arr=[4,7,10,12,13,19,22,37];
function checkPrime(arr)
{
var output=[],primes=[];
var x=arr.length;
for(i=2;i<=arr[x-1];i++)
primes[i]=1;
for(i=2;i<=arr[x-1];i++)
for(j=2;j<=Math.sqrt(arr[x-1]);j++)
primes[i*j]=0;
for(i=0;i<=arr[x-1];i++){
if(primes[i]==1){
output.push(i);
}
}
return output;
}
console.log(checkPrime(arr));
When creating your output list, you want to compare against the values in arr, not the indices, so you need to replace primes[i] with primes[arr[i]].
So this:
if (primes[i] == 1) {
output.push(i);
}
Becomes this:
if (primes[arr[i]] == 1) {
output.push(arr[i]);
}

Categories

Resources