I need some help with my code. I try to insert only one value in each array. I need to fill in the row first and after that, if the row is full then move to the next column. I try to solve this part for a couple of days but I fail. So here is my code
const testData = [1,2,3,4,5,6,7,8,9];
const create2dArray = (row, column) => {
var result = [];
for(let i = 0; i< row; i++){
result[i]= [];
for(let j = 0; j<column; j++){
result[i][j] = [];
for(let e = 0; e < testData.length; e++){
result[i][j] = [testData[e]];
}
}
}
return result;
}
let Column = 5
let Row = 5
filterQuotaData(EnrollmentQuota);
var ground = create2dArray(Column,Row);
console.log(ground);
Suppose the output is :
[1],[2],[3],[4],[5]
[6],[7],[8],[9],[]
[],[],[],[],[]
[],[],[],[],[]
[],[],[],[],[]
instead, I got:
[9],[9],[9],[9],[9]
[9],[9],[9],[9],[9]
[9],[9],[9],[9],[9]
[9],[9],[9],[9],[9]
[9],[9],[9],[9],[9]
I hope someone can help me to solve this problem
Following code
const testData = [1,2,3,4,5,6,7,8,9];
const create2dArray = (row, column) => {
var result = [];
k = 0
for(let i = 0; i< row; i++){
result[i]= [];
for(let j = 0; j<column; j++){
if(k < testData.length) {
result[i][j] = [testData[k]];
} else {
result[i][j] = [];
}
k++
}
}
return result;
}
let Column = 5
let Row = 5
//filterQuotaData(EnrollmentQuota);
var ground = create2dArray(Column,Row);
console.log(ground);
produces
[
[ [ 1 ], [ 2 ], [ 3 ], [ 4 ], [ 5 ] ],
[ [ 6 ], [ 7 ], [ 8 ], [ 9 ], [] ],
[ [], [], [], [], [] ],
[ [], [], [], [], [] ],
[ [], [], [], [], [] ]
]
Does it what you need?
What's happening in your code is that you have the 3rd loop adding everything to each column from 2nd loop. The reason why they are all 9s is because you are overwriting each column by using an assignment instead of adding it to the array:
// 3rd loop
array[0][0][0] = 1 // 1st iteration [[[1],...]]
array[0][0][1] = 2 // 2nd iteration [[[2],...]]
Here's an example that uses 2 loops and pushes sub-arrays and shifts from test array.
const test = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const create2dArray = (row, column) => {
let result = [];
for (let r = 0; r < row; r++) {
result.push([]);
for (let c = 0; c < column; c++) {
let data = test.length < 1 ? [] : [test.shift()]
result[r].push(data);
}
}
return result;
}
let row = 5, col = 5;
let ground = create2dArray(row, col);
console.log(JSON.stringify(ground));
Related
Take the following function to generate a square multiplication table:
function getMultTable(n) {
/* generate multiplication table from 1 to n */
let table = new Array(n);
for (let i=1; i<=n; i++) {
table[i-1] = new Array(n);
for (let j=1; j<=n; j++) {
table[i-1][j-1] = i*j;
}
}
return table;
}
console.log(getMultTable(3));
// [
// [ 1, 2, 3 ],
// [ 2, 4, 6 ],
// [ 3, 6, 9 ]
// ]
Why can't the following be done instead?
function getMultTable(n) {
let table = new Array(n);
for (let i=1; i<=n; i++) {
for (let j=1; j<=n; j++) {
table[i-1][j-1] = i*j;
}
}
return table;
}
In other words, why can't a multi-dimensional array be created on-the-fly in javascript, or is it possible to do that some other way?
Let's start from the basics, why you can't do the following
let arr;
arr[0] = 1
The answer is because arr is undefined. Well, when an array is initialized it is initialized with all its entries undefined. The operation table[i-1][j-1] = i*j is equivalent to
const row = table[i-1];
row[j-1] = i*j
So, when the table is created all its items are undefined, and the statement row[j-1] = i*j, is trying to set a property of row, in other words setting a property of undefined.
The reason is similar to why you can't run this
function getMultTable(n) {
let table;
for (let i=1; i<=n; i++) {
for (let j=1; j<=n; j++) {
table[i-1][j-1] = i*j;
}
}
return table;
}
Only that in this case your problem is trying to read a property from undefined
You can do it something like this:
let arr = new Array(n).fill().map(el => new Array(n).fill());
I am attempting to count up the index 1 values of the arrays within nested arrays. My desired output is:
[ [ [ 0, 0 ], [ 0, 1], [ 0, 2 ] ] ]
However I am getting the following as my output:
[ [ [ 0, 2 ], [ 0, 2 ], [ 0, 2 ] ] ]
Here is the code I am running, I am assuming the issue falls in the second for loop:
let width = 3
let height = 1
var grid = [];
let y = 0
for(var i=0; i<height; i++) {
grid[i] = new Array(width).fill([0,0])
}
let currentRow = grid[0]
for (let j = 0; j<grid[0].length; j++){
currentRow[j][1] = j
}
Thanks for helping!
change your code to
let width = 3;
let height = 1;
var grid = [];
let y = 0;
for (var i = 0; i < height; i++) {
grid[i] = new Array(width);
for (let j = 0; j < grid[i].length; j++) {
grid[i][j] = [0, 0];
}
}
let currentRow = grid[0];
for (let j = 0; j < grid[0].length; j++) {
currentRow[j][1] = j;
}
when you use grid[i] = new Array(width).fill([0,0]) you are saving one instance of [0,0] in your grid[i] array ,it means currentRow[0]==currentRow[1] is true, so when you change the currentRow[j][1] all of currentRow elements get changed, in your last step of second loop you change currentRow[2][1]=2 so all of currentRow elements get changed in this way.
I have an array like this:
var products = [
['date1','prod1',1,2],
['date2','prod2',3,4],
['date3','prod3',5,6],
['date4','prod4',7,8],
['date5','prod5',9,0]
];
And need to pull the integers out of the array and format it like this:
var newProductsArray = [[1,3,5,7,9],[2,4,6,8,0]];
It needs to be able to be dynamic and expand because the products array will have more "columns".
I have this code but it's doing it backwards and can't figure out how to loop through and just break up the arrays. I am sure it's something simple I'm missing.
var metricStartPosition = 2;
var dataSetInnerArray = [];
var dataSetArray = [];
for (var i = 0; i < array.length; i++) {
for (var k = metricStartPosition; k < array[i].length; k++) {
dataSetInnerArray.push(array[i][k]);
};
dataSetArray.push(dataSetInnerArray);
dataSetInnerArray = [];
};
You can do something like this:
var products = [
['date1','prod1',1,2,'a','b'],
['date2','prod2',3,4,'c','d'],
['date3','prod3',5,6,'e','f'],
['date4','prod4',7,8,'g','h'],
['date5','prod5',9,0,'i','j']
];
var metricStartPosition = 2;
var newProductsArray = products.reduce(function(output, item) {
item.slice(metricStartPosition).forEach(function(v, i) {
(output[i] || (output[i] = [])).push(v);
});
return output;
}, []);
console.log(JSON.stringify(newProductsArray));
Should work with any number of columns.
Of course you could use nested .forEach() loops or old-school nested for loops instead of .forEach() inside .reduce().
If I got your question correctly, inverting the order of the two for loops will do it:
var metricStartPosition = 2;
var dataSetInnerArray = [];
var dataSetArray = [];
for (var k = metricStartPosition; k < products[0].length; k++) {
for (var i = 0; i < products.length; i++) {
dataSetInnerArray.push(products[i][k]);
};
dataSetArray.push(dataSetInnerArray);
dataSetInnerArray = [];
};
Related Post
This should flip the array.
var newArray = array[0].map(function(col, i) {
return array.map(function(row) {
return row[i]
})
});
As a function this is:
function foo (array) {
var newArray = array[0].map(function(col, i) {
return array.map(function(row) {
return row[i]
})
});
return newArray;
}
By flip the array I mean this:
1 2 3 1 4 7
4 5 6 -> 2 5 8
7 8 9 3 6 9
And in your case:
var products = [
['date1','prod1',1,2],
['date2','prod2',3,4],
['date3','prod3',5,6],
['date4','prod4',7,8],
['date5','prod5',9,0]
];
var newProducts = [
['date1','date2','date3','date4','date5'],
['prod1','prod2','prod3','prod4','prod5'],
[1,3,5,7,9],
[2,4,6,8,0]
];
You could try and index all the columns one-by-one (assuming all the rows of the data is of the same types column-wise:
arrayRow = products[0] //['date1','prod1',1,2]
newProductsArray = [];
intIndices = [];
arrayRow.forEach(function(data, i) {
if (typeof(data) === 'number')
intIndices.push(i);
});
// intIndices should be [2, 3]
and then iterate through the whole products array to get all the columns:
intIndices.forEach(function (colIndex) {
innerArray = [];
for (var i = 0; i < products.length; i++) {
innerArray.push(products[i][colIndex]);
}
newProductsArray.push(innerArray);
});
// you should get nested arrays with all the integer columns
// [ [ 1, 3, 5, 7, 9 ],
// [ 2, 4, 6, 8, 0 ] ]
I want to duplicate certain arrays in arrays using JavaScript, for example:
var res = [["1,2,3",100,50],["4,5",75,10],["6",20,90]];
var res2 = [];
for(var z in res) {
var row = res[z];
var keys = row[0].split(',')
for(var y in keys) {
var key = keys[y];
res2.push([key,row[1]/keys.length,row[2]/keys.length]);
}
}
/*
[ [ '1', 33.333333333333336, 16.666666666666668 ],
[ '2', 33.333333333333336, 16.666666666666668 ],
[ '3', 33.333333333333336, 16.666666666666668 ],
[ '4', 37.5, 5 ],
[ '5', 37.5, 5 ],
[ '6', 20, 90 ] ]
*/
The arrays are really-really long, is it possible to do this in-place (res, without res2)?
You can use splice for a true in-place processing of res:
for (var i = 0; i < res.length; ) {
var row = res[i];
var keys = row[0].split(',')
res.splice(i, 1); // Remove old element
// Insert new elements at current position
for (var j in keys)
res.splice(i++, 0, [keys[j], row[1] / keys.length, row[2] / keys.length]);
}
Result:
[
["1", 33.333333333333336, 16.666666666666668],
["2", 33.333333333333336, 16.666666666666668],
["3", 33.333333333333336, 16.666666666666668],
["4", 37.5, 5],
["5", 37.5, 5],
["6", 20, 90]
]
EDIT:
Another trick to avoid splices is to extend the size of res and start filling it from the end to the beginning:
var n = res.length;
// Precalculate new length
var length = 0;
for (var i = 0; i < res.length; i++)
length += res[i][0].split(',').length;
// Change length of array
res.length = length;
// Start filling from end to start
for (var i = n - 1, k = length - 1; i >= 0; i--) {
var row = res[i];
var keys = row[0].split(',');
for (var j = keys.length - 1; j >= 0; j--)
res[k--] = [keys[j], row[1] / keys.length, row[2] / keys.length];
}
You can use reduce function something like this
var res = [["1,2,3",100,50],["4,5",75,10],["6",20,90]];
var r = res.reduce(function(acc,curr){
return acc.concat(curr[0].split(',').map(function(el,_,cursplit){
return [el, curr[1]/cursplit.length,curr[2]/cursplit.length];
}));
},[]);
but i'm not sure that it more readable
var res = [["1,2,3",100,50],["4,5",75,10],["6",20,90]];
var r = res.reduce(function(acc,curr){
return acc.concat(curr[0].split(',').map(function(el,_,cursplit){
return [el, curr[1]/cursplit.length,curr[2]/cursplit.length];
}));
},[]);
document.getElementById('d').innerHTML = r.join('<br>');
<div id="d"></div>
UPDATE
another variant with mutate res
for(var i=0,len=res.length;i<len;i++){
var cur = res.shift();
cur[0].split(',').forEach(function(el,_,cursplit){
res.push([el, cur[1]/cursplit.length,cur[2]/cursplit.length]);
});
}
var res = [["1,2,3",100,50],["4,5",75,10],["6",20,90]];
for(var i=0,len=res.length;i<len;i++){
var cur = res.shift();
cur[0].split(',').forEach(function(el,_,cursplit){
res.push([el, cur[1]/cursplit.length,cur[2]/cursplit.length]);
});
}
document.getElementById('d').innerHTML = res.join('<br>');
<div id="d"></div>
You can get it with Array.reduce
var res = [["1,2,3",100,50],["4,5",75,10],["6",20,90]];
res = res.reduce(function(a, b){
var parts = b[0].split(',');
parts.forEach(function(i){
a.push([i, b[1]/parts.length, b[2]/parts.length]);
});
return a;
}, []);
But, I believe this still eat double memory :)
Another solution (with res2, but more economy):
It get source entities one-by-one, process it and gc allowed to clean memory...
var res2 = [];
while (res.length) {
var cur = res.shift();
var ids = cur[0].split(',')
ids.forEach(function(i){
res2.push(i, cur[1]/ids.length, cur[2]/ids.length);
});
}
this code http://jsfiddle.net/minagabriel/5MQ77/
var flowShadeBigArray =[] ;
var x = [7, 411, 780]
var y = [286, 712, 1058]
for( var i = 0 ; i< x.length;i++){
for(var index = x[i]; index <= y[i] ; index++ ){
var temp = [] ;
temp.push(index) ;
flowShadeBigArray.push(temp);
}
}
console.log(JSON.stringify(flowShadeBigArray));
generate the following array
[[7],[8],[9],[10],[11],[12],[13],[14]................[1056],[1057],[1058]]
i want to create a three arrays inside flowShadeBigArray and have the [x[i] ... y[i] ]
grouped together:
example
[ [ [7]....[286] ] , [ [411]...[712] ] ,[ [780]...[1058] ] ]
NOTE i still need to keep each of these numbers as an array so i can use it an an index for something else
THANKS
Just move the temp initialization to the first loop, before the second, and the .push() to the first loop after the second (or before, doesn't matter).
var flowShadeBigArray = [];
var x = [7, 411, 780]
var y = [286, 712, 1058]
for (var i = 0; i < x.length; i++) {
var temp = [];
for (var index = x[i]; index <= y[i]; index++) {
temp.push(index);
}
flowShadeBigArray.push(temp);
}
http://jsfiddle.net/5MQ77/1/
If each individual number belongs in its own Array, then change this:
flowShadeBigArray.push(temp);
to this:
flowShadeBigArray.push([temp]);
-edited
function range(from, to) {
var arr = [];
while (from <= to) {
arr.push([i++]);
}
return arr;
}
var result = [];
for (var i=0; i<x.length; i++) {
result.push(range(x[i], y[i]));
}