javascript how to pass each element in an array to different var - javascript

I am new to javascript and recently have a problem to passing elements from array to var.
For example, I have an array like var anArray = [[a1,a2,a3],[b1,b2,b3],[c1,c2,c3]], and I have 3 different var a , b and c.
after some loop codes,
what I would like to see is:
while a=a1, b should be b1 and c=c1
while a=a2, b=b2 and c=c2
while a=a3, b=b3, c=c3
also pls consider that what if I have array like:
[[a1,a2,a3],[b1,b2,b3]] which will result a=a1 while b=b1, a=a2 while b=b2 etc.
or [[a1,a2],[b1,b2],[c1,c2]] which will result a=a1 while b=b1 and c=c1, a=a2 while b=b2 and c=c2
If my question is still not clear enough, please comments it and I will update it.
I really appreciate all the comments and the code that you have made! Many thanks!

You have a bunch of pieces backwards and in the wrong place:
var anArray = [[1,2],[1,2]];
for(var i=0;i <= anArray.length - 1;i++)
{
for(var j=0;j<anArray[i].length;j++){
var a = anArray[i][j];
var b = anArray[i + 1][j];
alert("a: "+a+" and b: "+b);
}
}
Edit: adjusted after you changed your entire question.

Let say that we have have an array like thisvar anArray = [[1,2,3],[4,5,6]];
and if you want to alert this a=14;b=25;c=36; then you can use this code
var anArray = [[1,2,3],[4,5,6]];
for ( i = 0; i < anArray.length; i++ ) {
var l = anArray[i];
for ( m = 0; m < l.length; m++ ){
this["a"+i+m.toString()] = l[m];
}
}
alert("a = "+ a00 + a10.toString());
alert("b = "+ a01 + a11.toString());
alert("c = "+ a02 + a12.toString());
Where a00=1; a01=2; a02=3; these are the elements of the first array.(the middle nr. tells the array so for the first array we use 0).
Then we have a10=4; a11=5; a12=6; these are the elements of the 2nd array.(the middle nr. tells the array so for the second array we use 1).
All you have to do is just replace this arrayvar anArray = [[1,2,3],[4,5,6]] with yours and let
javascript do its job.

After you clarified your question I got a general idea of what you want. I think this is what you want to achieve. The example is dynamic so that as long as the length of item in the array is equal.
var anArray = [[1,2,3],[4,5,6],[7,8,9]];
for(var j=0;j<anArray[0].length;j++){
var values = [];
for(var i=0;i<anArray.length;i++) {
values[i] = anArray[i][j];
}
//Do what you want with the values below. I chose to show them in a alert message
var text = '';
for(var i=0;i<anArray.length;i++) {
if(text.length>0){ text += ',' };
text += values[i];
}
window.alert('Values: ' + text);
}
PS: There were not 1 but a few things wrong with your code.

Related

multidimensional array indexOf not working js

I'm trying to find an index of a number in a 2d array, but console gives out
Uncaught TypeError: block[((a * 10) + c)].indexOf is not a function
I think it has something to do with the way of accessing the array element, but can't seem to find the problem.
Here's the code.
var block = [];
var temp;
var del;
for(var a = 0;a < 9;a++){
for(var b = 0;b < 9;b++){
temp = parseInt(prompt("enter element number " + b + " of row number " + a));
console.log(temp);
if(temp>0){
block[a*10+b] = temp;
}else{
block[a*10+b] = [1,2,3,4,5,6,7,8,9];
}
// console.log(block[a*10+b]);
}
}
for(var a = 0;a < 9;a++){
for(var b = 0;b < 9;b++){
if(typeof(block[a][b]) == "number"){
for(var c = 0;c < 9;c++){
if(c != b){
del = block[a*10+c].indexOf(b);
block[a*10+c].splice(del,1);
}
}
}
}
}
You have a mix of data types assigned to the block array. When the user enters a value that is not numeric, you assign indeed a nested array to one of the block elements, but not so when the user enters a valid number.
From what I think you are doing (a Sudoko game?) this might be intended: the numbers are known values in the grid, the nested arrays represent a list of values that are still possible at that particular cell.
But then in the second part of your code, you should check in which of the two cases you are, as you only want to remove array elements if the value you are looking at is indeed an array. This test you can do with Array.isArray().
There are also some other issues in the second part of your script:
The expression block[a][b] is not consistent with how you have filled that array: it should be block[a*10+b] to be consistent.
the b in .indexOf(b) is wrong: you are not looking for that value, but for block[a*10+b].
the splice() is always executed, even if the indexOf returned -1. This leads to an undesired effect, because if the first argument to splice() is negative, the index really is counted from the end of the array, and still an element is removed from the array. This should not happen: you should only execute the splice if the indexOf result is non-negative.
Below I have put a working version, but in order to avoid the almost endless prompts, I have provided this snippet with a textarea where you can input the complete 9x9 grid in one go, and then press a button to start the execution of your code:
document.querySelector('button').onclick = function () {
var block = [];
var temp;
var del;
var text = document.querySelector('textarea').value.replace(/\s+/g, '');
for(var a = 0;a < 9;a++){
for(var b = 0;b < 9;b++){
temp = parseInt(text[a*9+b]); // <-- get char from text area
if(temp>0){
block[a*10+b] = temp;
}else{
block[a*10+b] = [1,2,3,4,5,6,7,8,9];
}
}
}
for(var a = 0;a < 9;a++){
for(var b = 0;b < 9;b++){
var num = block[a*10+b]; // <-- get content, fix the index issue
if(typeof num == "number"){
for(var c = 0;c < 9;c++){
if(c != b && Array.isArray(block[a*10+c])){ //<-- add array-test
del = block[a*10+c].indexOf(num); // <-- not b, but num
if (del > -1) // <-- only splice when found
block[a*10+c].splice(del,1);
}
}
}
}
}
document.querySelector('pre').textContent = 'block='+ JSON.stringify(block);
};
<textarea rows=9>
53..7....
6..195...
.98....6.
8...6...3
4..8.3..1
7...2...6
.6....28.
...419..5
....8..79
</textarea>
<button>Process</button>
<pre></pre>
Note that there are elements in block which remain null. I suppose you intended this: as you multiply a with 10, and only store 9 values per "row", there is always one index that remains untouched.
I haven't looked over your second for loop, but you can try applying similar logic there as in the snippet I've provided. The issue is that you need to create a temporary array inside the outer for loop over values of a (but NOT inside the inner, nested for loop over values of b). Inside the for loop for values of b, then, you need to push something into that temporary array (which I called temp). Then, outside of the b for loop, but before the next iteration of a, push that temporary array temp to the block array. In this way, you will generate a 2D array.
var block = [];
var del;
for(var a = 0; a < 9; a++) {
let temp = [];
for(var b = 0; b < 9; b++) {
let num = parseInt(prompt(`Enter element ${b} of row ${a}:`));
if (num > 0) {
temp.push(num);
} else {
// block[a*10+b] = [1,2,3,4,5,6,7,8,9];
temp.push(b);
}
}
block.push(temp);
}

How to format the element inside an array?

I have three arrays for example:
var name = ["wheel", "rectangle", "moon"];
var type = ["car", "shape", "sky"];
var all = [];
var temp = " ";
for (var i = 0; i < name.length; i++) {
temp = name[i] + " " + type[i];
all.push(temp);
}
for (var i = 0; i < name.length; i++) {
// I call here function to display all element of array `all`
}
The output is:
wheel car
rectangle shape
moon sky
But the format of output is not nice. I want to shift the element of array type before add them to array all, so I want the output to be like:
wheel car
rectangle shape
moon sky
My question is: how can I shift elements of the array to add them to another array and store them in a way that allows to me to display the elements like form above ?
But the form of output not nice
If you simply want to format the output in a better way, then try console.table
var name1 = [ "wheel","rectangle","moon" ];
var type = [ "car" , "shape", "sky"];
var all=[];
for (var i = 0; i< name1.length; i++)
{
all.push({ name : name1[i], type: type[i] });
}
console.table(all);
Try this fiddle to see the actual output since stack-snippet alters the behaviour of console api
You should calculate which is the longest string in the first array so to know in advance how many spaces you need to append to correctly pad the string
var n = ["wheel", "rectangle", "moon"];
var t = ["car", "shape", "sky"];
var all = [];
/* sorting the values of the first array by length desc,
* then get the length of the first element
*/
var padding = n.sort(function(a, b) {
return a.length <= b.length;
})[0].length + 1;
n.forEach(function(el, i) {
all.push(el + " ".repeat(padding - el.length) + t[i]);
});
Output
"rectangle car"
"wheel shape"
"moon sky"
codepen demo
First loop over the array and find the max length. Then loop again and add spaces.
<script >
var name=["wheel","rectangle","moon"];
var type=["car","shape","sky"];
var all=[];
var i=0;
var maxLength=0;
string temp=" ";
String.prototype.padLeft= function(len, c){
var r = '';
while(r.length < len) r += c;
return s+r;
}
for (i = 0; i< name.length; i++)
{
maxLength = Math.max(maxLength, name[i].length+type[i].length+1;
}
for (i = 0; i< name.length; i++)
{
temp=name[i]+type[i].padLeft(maxLength-name[i].length-type[i].length);
all.push(temp);
}
</script >
I would do as follows;
var id = ["wheel","rectangle","moon"],
type = ["car","shape","sky"];
id.longestStringLength = Math.max(...id.map(s => s.length));
type.longestStringLength = Math.max(...type.map(s => s.length));
id = id.map((s,_,a) => s + " ".repeat(a.longestStringLength-s.length));
type = type.map((s,_,a) => " ".repeat(a.longestStringLength-s.length) + s);
console.log(id,type);
Use \t instead of space while concatenating to make it aligned.
Why don't you just add tab '\t' and it will give you the desired output. Or you can append fixed number of spaces between the two array items.

Online quiz with radio buttons having same name

I'm making a simple Quiz using Js, the problem is that my inner loop (i.e i) is not works as expected.
I have taken 3 questions and each question has 3 radio options, options of each question have same name. all the options of fist question have name='cap', options of second question name='an' and third question is name='lang'.
My js function is as follows:
function my(){
var count=0;
var totalQuestions = 3;
var correctAnswers = 0;
var alertText;
var n=["cap","an","lang"];
var j,i;
for(j=0; j<n.length; ++j){
var x = document.getElementsByName('n[j]');
for(i = 0; i < x.length; ++i){
if (x[i].checked){
if (x[i].value == 'true'){
count=count+10;
correctAnswers++;
break;
}
}
}
}
if(correctAnswers == totalQuestions){
alertText = "Congratulations! You got all the questions right!";
}
else {
alertText = "You got " + correctAnswers + " correct answers and score is " + count;
}
alert(alertText);
}
Replace line
var x = document.getElementsByName('n[j]');
to
var x = document.getElementsByName(n[j]);
That's problem because for js getElementsByName('n[y]') means "get elements with name n[y]", but not item of list n, which contain name of elements you need to select.
Good Luck !
var x = document.getElementsByName('n[j]');
Should be
var x = document.getElementsByName(n[j])
getElementsByName returns all elements that match the name per docs.
The issue is you hardcoded the string 'n[j]' so its looking for all elements with the name 'n[j]'.
You actually want to look up the name from y our array n at index j So removing the quotes will actually evaluate that expression n[j]
Change your code from
var x = document.getElementsByName('n[j]');
To
var x = document.getElementsByName(n[j]);
Your existing code tries to find a element which has name='n[j]'ie: a string. But what you want is to evaluate the expression get the element with the name equal to evaluated value.

Apply for loop with variable

I am trying to condense my code because I have a lot of repetitive coding happening. I will need to apply this same example many times over. I want to create a for loop but my variable needs to increase as well. Right now I have my variable increasing but I am unable to implement my cell data into the variable. I think I am double assigning var h. I can't figure out how to get around this. Thank you for your help.
For Loop
for (var j = 2; j<15; j++){eval("var polebrea" +j);
var h = ("polebrea" +j)
}
h = document.getElementById("part1Table").rows[10].cells[2].innerHTML;
Code Attempting To Implement
polebrea2 = document.getElementById("part1Table").rows[10].cells[2].innerHTML;
polebrea3 = document.getElementById("part1Table").rows[10].cells[3].innerHTML;
polebrea4 = document.getElementById("part1Table").rows[10].cells[4].innerHTML;
polebrea5 = document.getElementById("part1Table").rows[10].cells[5].innerHTML;
(cont. to 15)
Inserting Variable
<script>document.write(polebrea2)</script>
Ignoring design dogma....use the string index form of property access to set your variables:
// window is a bad place for this....you should probably put it on another object e.g. var polbreas = {};
for (var i = 2; i<15; i++){
window["polbrea"+i] = document.getElementById("part1Table").rows[10].cells[i].innerHTML;
}
While not necessarily good practice to do what you are doing, you could try this:
var createVariable = function( index ){
var variableName = "polebrea" + index;
var objName = document.getElementById("part1Table").rows[10].cells[index].innerHTML;
return (variableName + " = " + objName + ";");
};
for (var j = 2; j<15; j++){
var objToWrite = createVariable(j);
console.log( objToWrite );
}

Why is the array empty

I am just starting to learn Unity3D javascript, this is my first try to learn, trying to copy a shuffle Objective-C code snippet i have, and I have the following code:
function Shuffle(theCardArray : Array) {
var dupeArray = new Array();
var count = theCardArray.length;
print("theCardArray: " + theCardArray);
dupeArray = theCardArray;
count = dupeArray.length;
print("A) Count dupeArray: " + count);
print("B) Count dupeArray: " + dupeArray.length);
theCardArray.Clear();
for (var i = 0; i < count; i++) {
// Select random element between i and the end of the array to swap it
var nElements = count - i;
var n = Random.Range(0, nElements);
print("#1");
print("C) Count dupeArray: " + dupeArray.length);
print("dupeArray: " + dupeArray);
var dummyString = dupeArray[n];
print("#2");
theCardArray.Push(dummyString);
print("#3");
}
}
I get the following in my prints:
theCardArray: back,D2,D3,D4,D5,D6,D7,D8,D9,D10,DJ,DQ,DK
A) Count dupeArray: 13
B) Count dupeArray: 13
'#1'
C) Count dupeArray: 0
At B) the dupeArray have 13 entities and at C) the dupeArray is empty!
Could someone please explain to me why the array is empty at C)?
BTW, i know there are other ways in Unity3D to achieve the same thing but this is for learning!
The final and real solution I came up with for this is:
Call ShuffleThis with:
arr = ShuffleThis(arr);
The Shuffle function:
function ShuffleThis(theCardArray : Array) : Array {
var size : int = theCardArray.length;
for (var i : int = 0; i < size; i++) {
var indexToSwap : int = Random.Range(i, size);
var oldValue = theCardArray[i];
theCardArray[i] = theCardArray[indexToSwap];
theCardArray[indexToSwap] = oldValue;
}
return theCardArray;
}
Source: Fisher-Yates Shuffle with UnityScript
It's because the array dupeArray is just a reference to the original array theCardArray, so when you clear the original array you are also clearing the duplicate array; by reference.
In order to resolve your issue you should clone the original array, this can be done using slice like this...
var dupeArray = theCardArray.slice(0);
Alternatively, it can also be done using the jQuery extend approach like this...
var dupeArray = $.extend(true, [], theCardArray);

Categories

Resources