Hi I have this example where I want my 1D array to be a 2D array 4x3
var array1 = [15, 33, 21, 39, 24, 27, 19, 7, 18, 28, 30, 38];
var i, j, t;
var positionarray1 = 0;
var array2 = new Array(4);
for (t = 0; t < 4; t++) {
array2[t] = new Array(3);
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 3; j++) {
array2[i][j] = array1[i];
array2[i][j] = array1[j];
}
positionarray1 = positionarray1 + 1; //I do this to know which value we are taking
}
console.log(array2);
My solution is only giving me the first numbers of the array1. Any idea?
i and j are indexes into the new 2D array that only run up to 0 to 3 and 0 to 2, which is why you are seeing the beginning values over and over. You need a way to index array1 that goes from 0 to 11.
It looks like you are on the right track with "positionarray1" and "position", though you need to move where you are incrementing it. You need to use that value when indexing array1 rather than i and j:
array2[i][j] = array1[positionarray1];
array2[i][j] = array1[positionarray1];
positionarray1++;
If you rename i to row and j to col, it makes is easier to see what is going on. Also, avoid magic numbers. I am seeing 3 and 4 all over the place. These can be replaced with parameter references. All you need to do it wrap your logic within a reusable function (as seen in the reshape function below).
The main algorithm is:
result[row][col] = arr[row * cols + col];
There is no need to track position, because it can be calculated from the current row and column.
const reshape = (arr, rows, cols) => {
const result = new Array(rows);
for (let row = 0; row < rows; row++) {
result[row] = new Array(cols);
}
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
result[row][col] = arr[row * cols + col];
}
}
return result;
};
const array1 = [15, 33, 21, 39, 24, 27, 19, 7, 18, 28, 30, 38];
const array2 = reshape(array1, 4, 3);
console.log(JSON.stringify(array2));
.as-console-wrapper { top: 0; max-height: 100% !important; }
var array1 = [15, 33, 21, 39, 24, 27, 19, 7, 18, 28, 30, 38];
var i, j, t;
var positionarray1 = 0;
var array2 = new Array(4);
for (t = 0; t < 4; t++) {
array2[t] = new Array(3);
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 3; j++) {
array2[i][j] = array1[i*3+j]; //here was the error
}
positionarray1 = positionarray1 + 1; //I do this to know which value we are taking
}
console.log(array2);
I just solved it thanks for your comments. I actually used one apportation, but it was 3 instead of 2.
solution with 1 loop for efficiency :
const arr1D = new Array(19).fill(undefined).map((_, i) => i);
const arr2D = [];
const cols = 3;
for (let i = 0, len = arr1D.length; i < len; ++i) {
const col = i % cols;
const row = Math.floor(i / cols);
if (!arr2D[row]) arr2D[row] = []; // create an array if not exist
arr2D[row][col] = arr1D[i];
}
console.log({ arr1D, arr2D });
Related
I need to write a program that creates a 2d array in variable "numbers" in rows (5) and columns (4). The elements of the array have to be consecutive integers starting at 1 and end at 20. I have to use "for" loop.
[ 1, 2, 3, 4 ],
[ 5, 6, 7, 8 ],
[ 9, 10, 11, 12 ],
[ 13, 14, 15, 16 ],
[ 17, 18, 19, 20 ],
So I came up with that:
const numbers = [];
const columns = 4;
const rows = 5;
for (let i = 0; i < rows; i++) {
numbers [i] = [];
for (let j = 0; j < columns; j++){
numbers [i][j] = j + 1;
}
}
console.log(numbers);
But the result of this is five identical rows, like this:
[ 1, 2, 3, 4 ],
[ 1, 2, 3, 4 ],
[ 1, 2, 3, 4 ],
[ 1, 2, 3, 4 ],
[ 1, 2, 3, 4 ]
Do you have any idea how to fix it? How to make second row starting from 5?
Here is some updated code. You need to add i*columns to every value
const numbers = [];
const columns = 4;
const rows = 5;
for (let i = 0; i < rows; i++) {
numbers[i] = [];
for (let j = 0; j < columns; j++){
numbers[i][j] = j + 1 + (i*columns);
}
}
console.log(numbers);
Looks like in the second loop, you should do numbers [i][j] = j * i; instead
Every time the outer for loop starts a new iteration, j is reset back to 0, which is why you keep getting rows starting with 1.
To fix this, you could declare a variable outside of the for loops that tracks the current number, and use that instead of j like so:
const numbers = [];
const columns = 4;
const rows = 5;
let currNum = 0;
for (let i = 0; i < rows; i++) {
numbers [i] = [];
for (let j = 0; j < columns; j++){
currNum++;
numbers [i][j] = currNum;
}
}
console.log(numbers);
Hi all and thanks in advance for your help.
So I would like to find the highest number in a 2-dimensional array.
Below is the code:
const matrix = [
[2, 56, 10],
[20, 34, 10],
[23, 144, 26]
];
let maximum = matrix[0][0];
for (var row = 0; row < matrix.length; row++) {
for (var col = 0; col < matrix.length; col++) {
if (matrix[row][col] > maximum) {
maximum = matrix[row][col];
};
};
};
document.write(' -- ', maximum);
Here is my problem - Could you please help me to understand why when I have more numbers in the array I cannot see the highest number - Find below an example ):
const matrix = [
[2, 56, 10, 14, 422, 3242],
[20, 34, 55, 100, 33, 422],
[23, 12, 14, 26, 203, 233]
];
let maximum = matrix[0][0];
for (var row = 0; row < matrix.length; row++) {
for (var col = 0; col < matrix.length; col++) {
if (matrix[row][col] > maximum) {
maximum = matrix[row][col];
};
};
};
document.write(' -- ', maximum);
row < matrix.length tests the correct thing. col < matrix.length does not: you should replace it with col < matrix[row].length.
However, there is an easier way, using some of the newer JavaScript features:
const matrix = [[2,56,10,14,422,3242],[20,34,55,100,33,422],[23,12,14,26,203,233]];
const maximum = Math.max(...matrix.flat())
console.log(maximum);
matrix.flat() will flatten the two-dimensional array into one dimension, ... syntax will put each value from the one-dimensional array as its own argument to Math.max, which then finds the biggest one.
There is one small mistake. When you iterate the column make sure you iterate the number of columns.
matrix.length gives you the number of rows and matrix[i].length gives you the number of columns.
const matrix = [[2,56,10,14,422,3242],[20,34,55,100,33,422],[23,12,14,26,203,233]];
let maximum = matrix[0][0];
for(var row = 0; row < matrix.length; row++){
for(var col = 0; col < matrix[row].length; col++){
if(matrix[row][col] > maximum){
maximum = matrix[row][col];
};
};
};
document.write(' -- ', maximum);
You are taking matrix.length for no. of column as well, but it gives you no. of rows i.e. 3 but in your case but no. of column is 6 . that's why it only check for 3 numbers
const matrix = [[2,56,10,14,422,3242],[20,34,55,100,33,422],[23,12,14,26,203,233]];
let maximum = matrix[0][0];
for(var row = 0; row < matrix.length; row++){
for(var col = 0; col < matrix[0].length; col++){ <--- Correction
if(matrix[row][col] > maximum){
maximum = matrix[row][col];
};
};
};
document.write(' -- ', maximum);
Also can use Array.prototype.reduce() combined with Math.max():
const matrix = [[2,56,10,14,422,3242],[20,34,55,100,33,422],[23,12,14,26,203,233]]
const maximum = matrix.reduce((a, c) => Math.max(a, ...c), 0)
console.log(maximum)
Example: [1, 4, 9, 78, 42, 4, 11, 56]
Here the duplicate value is 4 and the gap is 3.
I used the array for each array element but I want this query to be optimized.
In Javascript, the following code will do the same for you.
var temp = [1, 4, 9, 78, 42, 4, 11, 56];
var encountered = [];
//This function gets you all the indexes of `val` inside `arr` array.
function getAllIndexes(arr, val) {
var indexes = [], i;
for(i = 0; i < arr.length; i++)
if (arr[i] === val)
indexes.push(i);
return indexes;
}
for(var i=0;i<temp.length;i++) {
if(encountered[temp[i]]) continue;
else {
var indexes = getAllIndexes(temp, temp[i]);
encountered[temp[i]] = true;
if(indexes.length>1) {
var steps = indexes[1]-indexes[0]-1;
$('.container').append('Duplicate item: '+temp[i]+' steps: '+ steps+'<br/>');
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div class="container"></div>
The below solution will give you if multiple duplicates.
http://jsfiddle.net/saz1d6re - Console Output
http://jsfiddle.net/saz1d6re/2/ - HTML Output
var a = [1, 4, 9, 78, 42, 4, 11, 4, 9];
result = [];
verified = [];
for(var i =0; i<a.length; i++){
b = a[i];
temp = {};
temp.value = a[i];
temp.hasDuplicate = false;
temp.positions = [];
temp.differenceFromFirstOccurence = [];
if(verified.indexOf(b) === -1){
temp.positions = [i+1];
for(var j = 0; j <a.length; j++){
c = a[j];
if( i !== j && b === c){
temp.hasDuplicate = true;
temp.positions.push(j+1);
}
}
verified.push(b);
result.push(temp);
}
}
for(var i = 0; i < result.length; i++){
if(result[i].hasDuplicate){
firstPosition = result[i]['positions'][0];
for(var j = result[i]['positions'].length-1; j > 0; j--){
diff = result[i]['positions'][j] - firstPosition-1;
result[i].differenceFromFirstOccurence.push(diff);
}
}
result[i].differenceFromFirstOccurence.reverse();
}
console.log(result);
for(var i =0; i < result.length; i++){
if(result[i].hasDuplicate && result[i].differenceFromFirstOccurence.length){
console.log("The first occurence of "+result[i].value+" is at "+ result[i].positions[0]);
for(var j = 1; j < result[i].positions.length; j++){
console.log("The duplicate occurence of "+result[i].value+" is at "+ result[i].positions[j] +" and difference is "+ result[i].differenceFromFirstOccurence[j-1]);
}
}
}
You can try this approach. First map all elements that have duplicates, then filter out empty values.
const data = [1, 4, 9, 78, 42, 4, 11, 56];
let duplIndex;
const res = data.map((el, index) => {
duplIndex = data.indexOf(el, index+1);
if(duplIndex !== -1){
return {el:el, gap: duplIndex - (index + 1)}
}
}).filter((el) => {
return el !== undefined;
});
var axis_x = document.getElementById("x_axis").value; // 3
var axis_y = document.getElementById("y_axis").value; // 2
for (var i=1; i <= axis_x; i++){
axs_x.push(i); // [1,2,3]
alert(axs_x);
}
for(var j=1 ; j <= axis_y; j++){
axs_y.push(j); // [1,2]
alert(axs_y);
}
}
Please help me to solve this issue. The actual result I need is:
[11, 12, 21, 22, 31, 32]
If i understand correctly this is what you want
var axis_x = document.getElementById("x_axis").value;//3
var axis_y = document.getElementById("y_axis").value;//2
for (var i=1; i <= axis_x; i++){
for(var j=1 ; j <= axis_y; j++){
alert(axs_x);
alert(axs_y);
}
}
If you need to generate x/y-axis couples given by the value (innerHTML) of 2 divs, try this out:
function getAxisNum(id) {
var elem = document.getElementById(id);
if (elem) {
return parseInt(elem.innerHTML, 10);
}
return null;
}
function generate(x, y) {
var arr = [];
for (var i = 1; i <= x; i++) {
for (var j = 1; j <= y; j++) {
arr.push(i * 10 + j)
}
}
return arr;
}
var axis_x = getAxisNum('x_axis');
var axis_y = getAxisNum('y_axis');
alert(generate(axis_x, axis_y)); // [11, 12, 21, 22, 31, 32]
console.log(generate(axis_x, axis_y)); // [11, 12, 21, 22, 31, 32]
<div id="x_axis">3</div>
<div id="y_axis">2</div>
How would one push multiples of a number to an array? For example, if the input is (6), I want to create an array that holds [6, 12, 18, 24, 30, 36, etc...]
The most intuitive method to me does not work.
for (var i = 0; i < 10; i++) {
firstArray.push(arr[0] *= 2);
}
This multiplies the number that comes before it by 2, causing an exponential growth. [14, 28, 56, 112, 224, 448, 896, 1792, etc.]
How would one achieve this?
Problem:
The problem in the code, as commented by Pranav is the use of multiplication by two in the for loop.
Using i iterator index can solve the problem.
firstArray.push(6 * (i + 1));
As i is starting from 0, i + 1 will give the number which is 1-based.
Another Approach:
First add the number
var num = 6,
arr = [num];
Then add the number which is double of the previous in the array.
for (var i = 1; i < 10; i++) {
arr.push(arr[i - 1] + num);
}
var arr = [6];
for (var i = 1; i < 10; i++) {
arr.push(arr[i - 1] + arr[0]);
}
console.log(arr);
The same thing can also be done in single line using for loop.
var arr = [];
for (let i = 0, num = 6; i < 10; i++, num += 6) {
arr.push(num);
}
console.log(arr);
You can use map:
function multiplyArrayElement(num) {
return num * 2;
}
numbers = [6, 12, 18, 24, 30, 36];
newArray = numbers.map(multiplyArrayElement);
https://jsfiddle.net/25c4ff6y/
It's cleaner to use Array.from. Just beware of its browser support.
Array.from({length: 10},(v,i) => (i + 1) * 6)
try this one
for (var i = 0; i < 10; i++) {
firstArray.push(arr[0] * (i+1));
}
var arr = [];
var x = 6; //Your desired input number
var z;
for(var i=1;i<10;i++){
z = (x*i);
arr.push(z);
}
console.log(arr);
"One line" solution with Array.fill and Array.map functions:
var num = 6;
var arr = new Array(10).fill(0).map(function(v, k){ return num *(k + 1); });
console.log(arr); // [6, 12, 18, 24, 30, 36, 42, 48, 54, 60]