How to create multidimensional array for each row? - javascript

For a website I used a grid layout. What I want is to store all items per row inside a row.
I have an overall array that is calling arrWrap = [];. Now I want to create for each row an new array, where I store each time 4 items. So a new array should be created after the third item in a row.
How do I achieve this?
I use Javascript for this project.
var arrPos = [];
for (var i = 0; i < elements.length; ++i) {
arrPos[i] = i;
console.dir(arrPos[i]);
if (arrPos[i] > 3) {
alert(arrPos[i]);
};
}

var arrWrap = [];
var steps = 4;
for (var i = 0; i < elements.length; i=i+steps) {
arrWrap.push(elements.slice(i,i+steps));
}

This proposal feature the Array.prototype.reduce and offers two solutions:
Grouped by consecutive elements dataGroupedA
[
[ 0, 1, 2 ],
[ 3, 4, 5 ],
[ 6, 7, 8 ],
[ 9, 10, 11 ],
[ 12, 13, 14 ]
]
Grouped by the 5th element dataGroupedB
[
[ 0, 5, 10 ],
[ 1, 6, 11 ],
[ 2, 7, 12 ],
[ 3, 8, 13 ],
[ 4, 9, 14 ]
]
The calculation of index is the important part. The rest is standard default assignment and pushing the actual element.
var data = Array.apply(Array, { length: 15 }).map(function (_, i) { return i; }),
dataGroupedA = data.reduce(function (r, a, i) {
var index = i / 3 | 0;
r[index] = r[index] || [];
r[index].push(a);
return r;
}, []),
dataGroupedB = data.reduce(function (r, a, i) {
var index = i % 5;
r[index] = r[index] || [];
r[index].push(a);
return r;
}, []);
document.write('<pre>' + JSON.stringify(data, 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(dataGroupedA, 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(dataGroupedB, 0, 4) + '</pre>');

Please use the following code:
var cIndex= 0;
var data=[];
var cars = ["Saab", "Volvo", "BMW", "a", "v", "c", "q"];
for(var i = 0; i <= 3; i++)
{
cIndex = cIndex + 3;
var row = cars.slice(cIndex -3,cIndex );
data.push(row);
}
console.log(data);

Related

Javascript array.push replaces all elements instead of adding an array

I was just trying stuff out in Vanilla JS and ran into a problem where array.push does not push another array (row) whose elems got changed in a for loop, but rather replaces the whole array (mainArr). It would be better to show the code so please scroll below
function genArray(m, n) {
let mainArr = [];
let row = [];
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
row.push(j);
}
mainArr.push(row)
}
return mainArr;
}
let myArr = genArray(3, 2);
console.log(myArr);
/**
* outputs:
*
* [ [ 0, 1, 0, 1, 0, 1 ],
* [ 0, 1, 0, 1, 0, 1 ],
* [ 0, 1, 0, 1, 0, 1 ] ]
*
* why not:
*
* [ [ 0, 1 ],
* [ 0, 1, 0, 1 ],
* [ 0, 1, 0, 1, 0, 1 ] ]
*/
At first I thought it was just because of the reference being appended as this SOF answers says, but as the code shows it doesn't.
let arr1 = []
let arr2 = [1, 2]
arr1.push(arr2)
console.log(arr1); // [ [ 1, 2 ] ]
arr2 = [2, 4]
console.log(arr1); // still [ [ 1, 2 ] ]
let arr3 = []
let obj1 = {name: "John"}
arr3.push(obj1)
console.log(arr3); // [ {name: "John"}]
obj1.name = "Mike"
console.log(arr3); // [ {name: "Mike"} ]
You are updating the same array every time, so all inserted lists will eventually point to the same reference with the value set in the last iteration.
The following is a fix with an enhancement to reach the expected output:
function genArray(m, n) {
const mainArr = [];
for (let i = 0; i < m; i++) {
const row = [];
let count = i;
while(count-- >= 0) {
for (let j = 0; j < n; j++) {
row.push(j);
}
}
mainArr.push(row)
}
return mainArr;
}
console.log( genArray(3, 2) );
You can use Destructuring assignment instead of array.push.
just like this:
function genArray(m, n) {
let mainArr = [];
let row = [];
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
row=[...row,j];
}
mainArr.push(row)
}
return mainArr;
}
let myArr = genArray(3, 2);
console.log(myArr);

Make nested array to group array elements

I have array:
arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14];
Then I want to make group of 4 elements.
Every iteration, this array must be modified until it get's final face.
Step 1:
arr = [[1,2,3,4],5,6,7,8,9,10,11,12,13,14];
Step 2:
arr = [[1,2,3,4],[5,6,7,8],9,10,11,12,13,14];
Step 3:
arr = [[1,2,3,4],[5,6,7,8],[9,10,11,12],13,14];
Step 3:
arr = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14]];
How is this possible?
I tried this:
var array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14]
var i,j,temparray,chunk = 4;
for (i=0,j=array.length; i<j; i+=chunk) {
temparray = array.slice(i,i+chunk);
console.log(temparray);
}
But I don't know then how to save this chunk into own array and not in the new array.
Using Array#reduce method.
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],
newArr = arr.reduce((acc, item, index) => {
if ((index) % 4 === 0) {
acc.push([item]);
} else {
acc[acc.length - 1].push(item);
}
return acc;
}, []);
console.log(newArr); // [ [ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ], [ 9, 10, 11, 12 ], [ 13, 14 ] ]
You could splice the array until the length is smaller than the index of the last insertation.
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],
i = 0;
while (i < array.length) {
array.splice(i, 0, array.splice(i, 4));
console.log(JSON.stringify(array));
i++;
}
lodash probably has better performances than my implementation, but if you are looking to do so with vanilla javascript then you can like this (though many other ways are possible):
var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14];
var newArr = arr.reduce((acc, val, idx)=>{
if(idx % 4 === 0){
acc.push([]);
}
acc[acc.length-1].push(val)
return acc
}, [])
console.log(newArr);
The lodash method chunk will do this for you.
result = _.chunk(arr, 4);
function chunkArray(myArray, chunk_size){
var index = 0;
var arrayLength = myArray.length;
var tempArray = [];
for (index = 0; index < arrayLength; index += chunk_size) {
myChunk = myArray.slice(index, index+chunk_size);
// Do something if you want with the group
tempArray.push(myChunk);
}
return tempArray;
}
// Split in group of 3 items
var result = chunkArray([1,2,3,4,5,6,7,8], 3);
// Outputs : [ [1,2,3] , [4,5,6] ,[7,8] ]
console.log(result);
Just push it to the resulting array:
const chunk = 4, result = []
for (var i = 0, j = array.length; i < j; i += chunk) {
result.push(array.slice(i,i + chunk));
}
I thought it would be fun too if I add one more solution using recursive calls, Happy coding!
Test it here
function split(arr, offset, res){
//stop condition (offset exceeds len of array)
if(offset>arr.length)
return res;
//slice 4 elms
res.push(arr.slice(offset,offset+4));
//recursion
return split(arr, offset+4, res);
}
var res = split([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], 0, []);
console.log(res);

Group identical values in array

I have an array that has some values inside, and I wish to return another array that has the value grouped in to their own arrays.
So the result I am trying to achieve is something like this:
var arr = [1,1,2,2,2,3,3,4,4,4,4,5,6]
var groupedArr =[[1,1],[2,2,2],[3,3],[4,4,4,4],[5],[6]]
This proposal works with Array#reduce for sorted arrays.
var arr = [1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 5, 6],
groupedArr = arr.reduce(function (r, a, i) {
if (!i || a !== r[r.length - 1][0]) {
return r.concat([[a]]);
}
r[r.length - 1].push(a);
return r;
}, []);
document.write('<pre>' + JSON.stringify(groupedArr, 0, 4) + '</pre>');
Here you go. By the way, this works with unsorted array as well.
var arr = [1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 5, 6]
var grpdArr = [];
while(arr.length > 0){
var item = arr[0];
grpdArr.push(arr.filter(function(val) {
return val === item;
}));
arr = arr.filter(function(val){return val!==item});
}
//console.log(arr, grpdArr);
Well this should do. Pretty straight forward..,
You get the elements and then remove them.
With forEach and temporary array
var arr = [1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 5, 6];
var temp = [];
var res = [];
arr.forEach(function(e) {
if (temp.slice(-1) == e) temp.push(e);
else {
temp = [e];
res.push(temp);
}
});
document.write(JSON.stringify(res));
This may not be the most optimal version but should do. This also works for unsorted arrays.
function abc(arr) {
var newObj = new Object();
for (var i in arr) {
if (typeof newObj[arr[i]] == 'undefined') {
newObj[arr[i]] = new Array();
}
newObj[arr[i]].push(arr[i]);
}
var groupedArr = new Array();
for (i in newObj) {
groupedArr.push(newObj[i]);
}
return groupedArr;
}
console.log(abc([1, 1, 2, 2, 3, 3, 3, 4, 1]));
This is the most straightforward in my mind:
var arr = [1,1,2,2,2,3,3,4,4,4,4,5,6];
var grouped = {};
var groupedArr = [];
//accumulate the values in an object, each key is an array
for (var i = 0; i < arr.length; i++) {
if (!grouped[arr[i]]) grouped[arr[i]] = [];
grouped[arr[i]].push(arr[i]);
}
//loop through all the keys in the object and push the arrays to the master array
var keys = Object.keys(grouped);
for (var i = 0; i < keys.length; i++) {
groupedArr.push(grouped[keys[i]]);
}
console.log(groupedArr);
I think you could use the code below:
var arr = [1,1,2,2,2,3,3,4,4,4,4,5,6]
var groupedArray = [];
var temp = arr.sort();
var tempArray = [arr[0]];
for(var i = 0; i < temp.length - 1; ++i){
if(temp[i] == temp[i + 1]){
tempArray.push(temp[i + 1]);
}else{
groupedArray.push(tempArray);
tempArray = [temp[i + 1]];
}
}
groupedArray.push(tempArray);
Now the groupedArray will contain the Result

JavaScript - Making a sum of values in same row and column

How can I make a sum of values in same row and column and make another array (can be one-dimensional) of results.
Array [
[ 1, 1, 0, 1 ],
[ 1, 1, 1, 1 ],
[ 1, 1, 1, 1 ],
[ 1, 1, 0, 1 ]
]
var res = []; //the 1D array to hold the sums
var hArr = [
[ 1, 1, 0, 1 ],
[ 1, 1, 1, 1 ],
[ 1, 1, 1, 1 ],
[ 1, 1, 0, 1 ]
]; //your array
var vArr = []; //Now lets create an array of arrays with the columns of hArr
for (var j=0; j<hArr[0].length; j++) {
var temp = [];
for (var i=0; i<hArr.length; i++) {
temp.push(hArr[i][j]);
}
vArr.push(temp);
}
//sum all the element in the line - Vertically and Horizontally
function SumVH (hInd, vInd) {
var sum = 0;
//add horizontal elements
for(var i=0; i<hArr[hInd].length; i++) {
sum += hArr[hInd][i];
}
//add vertical elements
for(var i=0; i<vArr[vInd].length; i++) {
sum += vArr[vInd][i];
}
//console.log("hInd="+hInd+" vInd="+vInd+" Sum="+sum);
return sum;
}
// go through the main array and get result
var sumR = 0;
//sum of each row
for (var i=0; i<hArr.length; i++) {
for (var j=0; j<hArr[i].length; j++) {
sumR = SumVH(i,j) - (2 * hArr[i][j]);
res.push(sumR);
}
}
Please check it now. The variable res holds the result
For my array writen above I want result array like 7, 7, 5, 7, 8, 8,
6, 8, 8, 8, 6, 8, 7, 7, 5, 7
Now the above code does not count the number itself in sum. But to get the result as your comment, please replace this line
sumR = SumVH(i,j) - (2 * hArr[i][j]);
with
sumR = SumVH(i,j);
Thank you.

Convert simple array into two-dimensional array (matrix)

Imagine I have an array:
A = Array(1, 2, 3, 4, 5, 6, 7, 8, 9);
And I want it to convert into 2-dimensional array (matrix of N x M), for instance like this:
A = Array(Array(1, 2, 3), Array(4, 5, 6), Array(7, 8, 9));
Note, that rows and columns of the matrix is changeable.
Something like this?
function listToMatrix(list, elementsPerSubArray) {
var matrix = [], i, k;
for (i = 0, k = -1; i < list.length; i++) {
if (i % elementsPerSubArray === 0) {
k++;
matrix[k] = [];
}
matrix[k].push(list[i]);
}
return matrix;
}
Usage:
var matrix = listToMatrix([1, 2, 3, 4, 4, 5, 6, 7, 8, 9], 3);
// result: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
You can use the Array.prototype.reduce function to do this in one line.
ECMAScript 6 style:
myArr.reduce((rows, key, index) => (index % 3 == 0 ? rows.push([key])
: rows[rows.length-1].push(key)) && rows, []);
"Normal" JavaScript:
myArr.reduce(function (rows, key, index) {
return (index % 3 == 0 ? rows.push([key])
: rows[rows.length-1].push(key)) && rows;
}, []);
You can change the 3 to whatever you want the number of columns to be, or better yet, put it in a reusable function:
ECMAScript 6 style:
const toMatrix = (arr, width) =>
arr.reduce((rows, key, index) => (index % width == 0 ? rows.push([key])
: rows[rows.length-1].push(key)) && rows, []);
"Normal" JavaScript:
function toMatrix(arr, width) {
return arr.reduce(function (rows, key, index) {
return (index % width == 0 ? rows.push([key])
: rows[rows.length-1].push(key)) && rows;
}, []);
}
This code is generic no need to worry about size and array, works universally
function TwoDimensional(arr, size)
{
var res = [];
for(var i=0;i < arr.length;i = i+size)
res.push(arr.slice(i,i+size));
return res;
}
Defining empty array.
Iterate according to the size so we will get specified chunk.That's why I am incrementing i with size, because size can be 2,3,4,5,6......
Here, first I am slicing from i to (i+size) and then I am pushing it to empty array res.
Return the two-dimensional array.
The cleanest way I could come up with when stumbling across this myself was the following:
const arrayToMatrix = (array, columns) => Array(Math.ceil(array.length / columns)).fill('').reduce((acc, cur, index) => {
return [...acc, [...array].splice(index * columns, columns)]
}, [])
where usage would be something like
const things = [
'item 1', 'item 2',
'item 1', 'item 2',
'item 1', 'item 2'
]
const result = arrayToMatrix(things, 2)
where result ends up being
[
['item 1', 'item 2'],
['item 1', 'item 2'],
['item 1', 'item 2']
]
How about something like:
var matrixify = function(arr, rows, cols) {
var matrix = [];
if (rows * cols === arr.length) {
for(var i = 0; i < arr.length; i+= cols) {
matrix.push(arr.slice(i, cols + i));
}
}
return matrix;
};
var a = [0, 1, 2, 3, 4, 5, 6, 7];
matrixify(a, 2, 4);
http://jsfiddle.net/andrewwhitaker/ERAUs/
Simply use two for loops:
var rowNum = 3;
var colNum = 3;
var k = 0;
var dest = new Array(rowNum);
for (i=0; i<rowNum; ++i) {
var tmp = new Array(colNum);
for (j=0; j<colNum; ++j) {
tmp[j] = src[k];
k++;
}
dest[i] = tmp;
}
function matrixify( source, count )
{
var matrixified = [];
var tmp;
// iterate through the source array
for( var i = 0; i < source.length; i++ )
{
// use modulous to make sure you have the correct length.
if( i % count == 0 )
{
// if tmp exists, push it to the return array
if( tmp && tmp.length ) matrixified.push(tmp);
// reset the temporary array
tmp = [];
}
// add the current source value to the temp array.
tmp.push(source[i])
}
// return the result
return matrixified;
}
If you want to actually replace an array's internal values, I believe you can call the following:
source.splice(0, source.length, matrixify(source,3));
This a simple way to convert an array to a two-dimensional array.
function twoDarray(arr, totalPerArray) {
let i = 0;
let twoDimension = []; // Store the generated two D array
let tempArr = [...arr]; // Avoid modifying original array
while (i < arr.length) {
let subArray = []; // Store 2D subArray
for (var j = 0; j < totalPerArray; j++) {
if (tempArr.length) subArray.push(tempArr.shift());
}
twoDimension[twoDimension.length] = subArray;
i += totalPerArray;
}
return twoDimension;
}
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
twoDarray(arr, 3); // [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]
function changeDimension(arr, size) {
var arrLen = arr.length;
var newArr = [];
var count=0;
var tempArr = [];
for(var i=0; i<arrLen; i++) {
count++;
tempArr.push(arr[i]);
if (count == size || i == arrLen-1) {
newArr.push(tempArr);
tempArr = [];
count = 0;
}
}
return newArr;
}
changeDimension([0, 1, 2, 3, 4, 5], 4);
function matrixify(array, n, m) {
var result = [];
for (var i = 0; i < n; i++) {
result[i] = array.splice(0, m);
}
return result;
}
a = matrixify(a, 3, 3);
function chunkArrToMultiDimArr(arr, size) {
var newArray = [];
while(arr.length > 0)
{
newArray.push(arr.slice(0, size));
arr = arr.slice(size);
}
return newArray;
}
//example - call function
chunkArrToMultiDimArr(["a", "b", "c", "d"], 2);
you can use push and slice like this
var array = [1,2,3,4,5,6,7,8,9] ;
var newarray = [[],[]] ;
newarray[0].push(array) ;
console.log(newarray[0]) ;
output will be
[[1, 2, 3, 4, 5, 6, 7, 8, 9]]
if you want divide array into 3 array
var array = [1,2,3,4,5,6,7,8,9] ;
var newarray = [[],[]] ;
newarray[0].push(array.slice(0,2)) ;
newarray[1].push(array.slice(3,5)) ;
newarray[2].push(array.slice(6,8)) ;
instead of three lines you can use splice
while(array.length) newarray.push(array.splice(0,3));
const x: any[] = ['abc', 'def', '532', '4ad', 'qwe', 'hf', 'fjgfj'];
// number of columns
const COL = 3;
const matrix = array.reduce((matrix, item, index) => {
if (index % COL === 0) {
matrix.push([]);
}
matrix[matrix.length - 1].push(item);
return matrix;
}, [])
console.log(matrix);
Using the Array grouping proposal (currently stage 3), you can now also do something like the following:
function chunkArray(array, perChunk) {
return Object.values(array.group((_, i) => i / perChunk | 0));
}
See also the MDN documentation for Array.prototype.group().
Simplest way with ES6 using Array.from()
const matrixify = (arr, size) =>
Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>
arr.slice(i * size, i * size + size));
const list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] ;
console.log(matrixify(list, 3));
Another stab at it,
Creating an empty matrix (Array of row arrays)
Iterating arr and assigning to matching rows
function arrayToMatrix(arr, wantedRows) {
// create a empty matrix (wantedRows Array of Arrays]
// with arr in scope
return new Array(wantedRows).fill(arr)
// replace with the next row from arr
.map(() => arr.splice(0, wantedRows))
}
// Initialize arr
arr = new Array(16).fill(0).map((val, i) => i)
// call!!
console.log(arrayToMatrix(arr, 4));
// Trying to make it nice
const arrToMat = (arr, wantedRows) => new Array(wantedRows).fill(arr)
.map(() => arr.splice(0, wantedRows))
(like in: this one)
(and: this one from other thread)
MatArray Class?
Extending an Array to add to a prototype, seems useful, it does need some features to complement the Array methods, maybe there is a case for a kind of MatArray Class? also for multidimensional mats and flattening them, maybe, maybe not..
1D Array convert 2D array via rows number:
function twoDimensional(array, row) {
let newArray = [];
let arraySize = Math.floor(array.length / row);
let extraArraySize = array.length % row;
while (array.length) {
if (!!extraArraySize) {
newArray.push(array.splice(0, arraySize + 1));
extraArraySize--;
} else {
newArray.push(array.splice(0, arraySize));
}
}
return newArray;
}
function twoDimensional(array, row) {
let newArray = [];
let arraySize = Math.floor(array.length / row);
let extraArraySize = array.length % row;
while (array.length) {
if (!!extraArraySize) {
newArray.push(array.splice(0, arraySize + 1));
extraArraySize--;
} else {
newArray.push(array.splice(0, arraySize));
}
}
return newArray;
}
console.log(twoDimensional([1,2,3,4,5,6,7,8,9,10,11,12,13,14], 3))
Short answer use:
const gridArray=(a,b)=>{const d=[];return a.forEach((e,f)=>{const
h=Math.floor(f/b);d[h]=d[h]||[],d[h][f%b]=a[f]}),d};
Where:
a: is the array
b: is the number of columns
An awesome repository here .
api : masfufa.js
sample : masfufa.html
According to that sample , the following snippet resolve the issue :
jsdk.getAPI('my');
var A=[1, 2, 3, 4, 5, 6, 7, 8, 9];
var MX=myAPI.getInstance('masfufa',{data:A,dim:'3x3'});
then :
MX.get[0][0] // -> 1 (first)
MX.get[2][2] // ->9 (last)

Categories

Resources