Getting an array index from 2 values - javascript

I wasn't sure how to properly word the title.
I have 2 indexes from a 2D array (x and y) and need to multiply them together to get the index for a second array (1D), however it's not that simple 'cause if x or y equals zero, it'll return zero regardless of the other value.
I could get around this using nested loops shown below:
int count = 0;
for( int i = 0; i < x; i++ )
{
for( int j = 0; j < y; j++ )
{
count++;
}
}
//count now equals desired value
...but that seems awfully impractical.
To me this seems like something that should be incredibly simple and I've put off asking until now, thinking that might be the case.

Let’s use the following data to create an example:
var array_2d = [[0,1,2],[3,4,5]];
var array_1d = [0, 1, 2, 3, 4, 5];
If all of your sub arrays have the same size, you can simply multiply your i index by your sub array’s length, in order to find the corresponding “row” of your 1 dimensional array. Then you can simply add the “column” index of your array.
But this would only work if you are working with width-fixed matrixes.
var sub_dimensional_array_length = 3;
for (var i = 0; i < array_2d.length; i++) {
for (var j = 0; j < array_2d[i].length; j++) {
var array_1d_index = (sub_dimensional_array_length * i) + j;
console.log(array_2d[i][j], array_1d[array_1d_index]);
}
}

Related

Understanding get second lowest and second highest value in array

Good day fellow Stack-ers,
I must ask your pardon if this question has been asked before or if it seems elementary (I am only a Javascript novice).
I have been doing w3c js challenges lately: Write a JavaScript function which will take an array of numbers stored and find the second lowest and second greatest numbers.
Here is my answer:
var array = [3,8,5,6,5,7,1,9];
var outputArray = [];
function arrayTrim() {
var sortedArray = array.sort();
outputArray.push(sortedArray[1],array[array.length-2]);
return outputArray;
}
arrayTrim();
and here is the answer that they have provided:
function Second_Greatest_Lowest(arr_num) {
arr_num.sort(function(x,y) {
return x-y;
});
var uniqa = [arr_num[0]];
var result = [];
for(var j=1; j < arr_num.length; j++) {
if(arr_num[j-1] !== arr_num[j]) {
uniqa.push(arr_num[j]);
}
}
result.push(uniqa[1],uniqa[uniqa.length-2]);
return result.join(',');
}
alert(Second_Greatest_Lowest([1,2,3,4,5]));
I know that the for loop runs through until the length of the input, but I don't understand the if statement nested within the for loop. It seems like a long way around to the solution.
Thank you!
Your answer does not perform correct for input such as f.e. [3,8,5,6,5,7,1,1,9]. Your proposed solution returns 1 as the second lowest number here – whereas it should actually be 3.
The solution suggested by the site takes that into account – that is what the if inside the loop is for, it checks if the current number is the same as the previous one. If that’s the case, it gets ignored. That way, every number will occur once, and that in turn allows to blindly pick the second element out of that sorted array and actually have it be the second lowest number.
It seems like a long way around to the solution
You took a short cut, that does not handle all edge cases correctly ;-)
The loop in question:
for(var j=1; j < arr_num.length; j++) {
if(arr_num[j-1] !== arr_num[j]) {
uniqa.push(arr_num[j]);
}
}
Provides some clue as to what it's doing by using a (reasonably) descriptive variable name: uniqa - or "unique array". The if statement is checking that the current element is not the same as the previous element - having sorted the array initially this works to give you a unique array - by only filling a new array if the element is indeed unique.
Thereafter the logic is the same as yours.
import java.util.Arrays;
public class BubbleWithMax_N_Min
{
public static void main(String[] agrs)
{
int temp;
int[] array = new int[5];
array[0] = 3;
array[1] = 99;
array[2] = 55;
array[3] = 2;
array[4] = 1;
System.out.println("the given array is:" + Arrays.toString(array));
for (int i = 0; i < array.length; i++)
{
System.out.println(array[i] + "");
}
for (int i = 0; i < array.length; i++)
{
for (int j = 1; j < array.length - i; j++)
{
if (array[j - 1] > array[j])
{
temp = array[j - 1];
array[j - 1] = array[j];
array[j] = temp;
}
}
}
System.out.println(" 2nd Min and 2nd Highest:");
for (int i = 0; i < 1; i++)
{
System.out.println(array[i+1]);
}
for (int i = 0; i < 1; i++)
{
int a= array.length-2;
System.out.println(array[a]);
}
}
}

Why is this incrementer returning NAN when if I hard code the index it works as expected?

I am trying to do a simple factorial code challenge, but with Javascript, when I try to get the index position by looping of the indexes, I get NAN. I understand that NAN is of the typeOf number, just that Javascript doesn't know which number. I don't see why that is happening in this case. Also how can I use get the index of an array by looping over them in Javascript? Thanks!
// Input = 4 Output = 24
// Input = 8 Output = 40320
var total = 0;
var factor_Array = [];
function FirstFactorial(num) {
for (var i = 1; i <= num; i++){
factor_Array.unshift(i);
// console.log(factor_Array);
}
for (var j = 0; j < factor_Array.length; j++){
// Why does this work??? But not when I use 'j' to grab the index position? Seems like BOTH ways should work
total = factor_Array[0] * factor_Array[0+1];
total = factor_Array[j] * factor_Array[j+1];
}
console.log(total);
//return num;
}
FirstFactorial(4);
Because when j = (factor_Array.length-1) it tries to access the j+1 element, which doesn't exist.
The following would work as you expect
for (var j = 0; j < (factor_Array.length-1); j++){
total = factor_Array[j] * factor_Array[j+1];
}
When you loop
for (var j = 0; j < factor_Array.length; j++){
total = factor_Array[j] * factor_Array[j+1];
}
Then then on the last iteration you will be out of the array bounds since
j = factor_Array.length - 1
and you're accessing j + 1.

Better way to assign unique numbers to 2D Array

My goal is to create a 2D Array, and assign a unique number from 0 to n for each in Javascript.
For example, if there is 5 rows and 5 cols, I first make an array of values containing the numbers from 0 to 24. I then want to shuffle those numbers and then if the number is less than 10, place a 'Y' for that spot in the Array or a 'N' if it's greater than or equal to 10. The end result should be 15 N's and 10 Y's randomly located.
I have the following code that does that, but I find it really inefficient and was wondering if there was a better way of doing it.
//Define Empty Array
test = new Array(rows);
for (var k = 0; k < rows; k++)
{
test[k] = Array(cols);
}
var values = [];
var index = 0;
var maxVals = (rows * cols);
//If maxVals is equal to 25, then the values array will hold "1,2,3,4, ... 24,25"
while(values.push(index++)<maxVals);
//Shuffle all those values so they're no longer in order
var shuffledValues = _.shuffle(values);
var i = 0;
var smallerThan = 10;
for (var x = 0; x < rows; x++)
{
for (var y = 0; y < cols; y++)
{
//Make all the numbers smaller than 10 a Y
if (shuffledValues[i] < smallerThan)
{
test[x][y] = "Y";
}
else
{
test[x][y] = "N";
}
i++;
}
}
Since you need to iterate over all n = rows×columns elements in your array to set a value your algorithm already has a minimum time complexity of O(n). The loop that creates the indexes array is another n and the shuffle method (if implemented correctly) should shuffle in n as well, so you algorithm is already O(3n) = O(n). While you may be able to reduce the constant factor of 3 it's not going to make any huge difference as your number of rows and columns grows large.
If you don't need exactly a certain number to be "Y" or "N" and just a ratio of them on average then you could do this instead:
var ratio = 0.5; //use your required ratio here
for (var x = 0; x < rows; x++)
{
for (var y = 0; y < cols; y++)
{
test[x][y] = Math.random() < ratio ? "Y" : "N";
}
}

Get index of array at equal points

Let's say you have an array of length 20. You want to access 3 equally spaced indices: 0, 9, 19.
How can you do this with any length of array and any number of sections?
I feel like there must be an elegant way of doing it, but the only way I can think of is finding the section size (var len = 20 / (3 -1)), iterating over the total number of sections (for (var i = 0; i < 3; i++) { var row = data[len * i]; }), and then subtracting one for non-zero indices.
You could try something like this (where console.log is used now you can call your array):
var amount = 3;
var total = 20;
var size = (total - 1) / (amount - 1);
for(var i = 0; i < amount; i++) {
console.log(Math.floor(size * i));
}
There isn't realy a more elegant solution.

why is my loop only seeing the value of the first array element?

function Deal()
{
var suffledDeck:Array;
var playerOneCards: Array;
var playerTwoCards: Array;
var first:int =0;
var second:int = 1;
suffledDeck = new Array();
playerOneCards = new Array();
playerTwoCards = new Array();
//var CardLeft:int = Deck.length;
for(var i = 0; i < Deck.length; i++)
{
Debug.Log(Deck.length);
var ranNum = Random.Range(1,Deck.length);
suffledDeck.Add(Deck[ranNum]);
Debug.Log("suffled deck: " + suffledDeck.length);
}
//var halfDeck: int = (suffledDeck.length / 2);
for(var j = 0; j <=26 ; j++)
{
Debug.Log(first);
Debug.Log(second);
playerOneCards.Add(suffledDeck[first]);
playerTwoCards.Add(suffledDeck[second]);
Debug.Log(playerOneCards[first].img);
Debug.Log(playerTwoCards[second].img);
first += 2;
second += 2;
}
}
when i begin to split the array into 2 separate arrays it begins to ignore every element except the first element. the suffleDeck[] has 52 Card objects loaded in and im trying to split the array so that each player can have there own deck.
Console window for debug purpose: http://puu.sh/2dqZm
I believe the problem is var ranNum = Random.Range(1,Deck.length).
ranNum should be generating a random index between 0 to Deck.length - 1 because array indices start at 0 (not 1).
The problem is with these logging statements:
Debug.Log(playerOneCards[first].img);
Debug.Log(playerTwoCards[second].img);
first and second are valid indexes into suffledDeck, but each player's deck only has half as many cards. Try using j as the subscript in both logging statements instead of first or second.
You should also limit your loop to j < 26, not j <= 26. As it is, you are trying to put 27 cards in each player's deck.
because:
Debug.Log(playerTwoCards[second].img);
here second value us 1 while your array contains only one item that is at zero. causing ArgumentoutofRangeException.
so try:
for(var j = 0; j <=26 ; j++)
{
Debug.Log(first);
Debug.Log(second);
playerOneCards.Add(suffledDeck[first]);
playerTwoCards.Add(suffledDeck[second]);
Debug.Log(playerOneCards[j].img);
Debug.Log(playerTwoCards[j].img);
first += 2;
second += 2;
}

Categories