Resize multi-dimensional arrays to add empty columns and rows - javascript

How can I add empty columns and rows to a multi-dimensional array?
Example array:
// (1s are just a placeholder for any data)
let arr = [
[1,1,1,1],
[1,1,1,1],
[1,1,1,1],
];
After adding 3 empty columns and 2 rows:
let result = [
[1,1,1,1,"","",""],
[1,1,1,1,"","",""],
[1,1,1,1,"","",""],
["","","","","","",""],
["","","","","","",""],
];

let arr = [
[1,1,1,1],
[1,1,1,1],
[1,1,1,1],
];
let newCols = 3, newRows = 2
arr.forEach(i=>i.push(...Array(newCols).fill('')))
for(let i=0; i<newRows; i++) arr.push(Array(arr[0].length).fill(''))
console.log(arr)

In a scenario, where the existing length of inner arrays is always the same, you can follow these steps:
Add rows with empty elements with the same number of existing columns. You can use the Array.fill method for this.
Add the new columns to all the rows
It can look something like this:
function resizeArr() {
let arr = [
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
];
let newCols = 3;
let newRows = 2;
// Add new rows
for (let i = 0; i < newRows; i++) {
arr.push(Array(arr[0].length).fill(""))
}
//Add new empty cols
arr.forEach((row) => {
for (let i = 0; i < newCols; i++) {
row.push("")
}
});
console.log(arr)
}
resizeArr()

This adds newRows arrays of intended size (innerSize) to the array first, then «fills» all arrays to the intended size.
let arr= [
[1,1,1,1],
[1,1,1,1],
[1,1,1,1],
];
const newCols = 3,
newRows = 2,
innerSize = arr[0].length + newCols,
fillValue = "";
for(var i = 0; i < newRows; i++){
arr.push(new Array(innerSize).fill(fillValue));
}
arr = arr.map(x => x.concat(new Array(innerSize - x.length).fill(fillValue)));
console.log(JSON.stringify(arr));

Related

Remove similar duplicates from 2D array in JavaScript

I need to remove similar duplicates as well as real duplicates from 2D array in JavaScript.
let a = [
[5, 6],
[1,1],
[6,5],
[1,1],
[3,2],
[2,3]
]
function makeUnique(arr) {
var uniques = [];
var itemsFound = {};
for(var i = 0, l = arr.length; i < l; i++) {
var stringified = JSON.stringify(arr[i]);
if(itemsFound[stringified]) continue;
uniques.push(arr[i]);
itemsFound[stringified] = true;
}
return uniques;
}
a=makeUnique(a)
console.log(a);
I have got this output:
[ [ 5, 6 ], [ 1, 1 ], [ 6, 5 ], [ 3, 2 ], [ 2, 3 ] ]
Correct should be:
[ [ 5, 6 ], [ 1, 1 ], [ 2, 3 ] ]
My code removes correctly duplicates, but I need to remove similar duplicates also.
For example if I have [3,2] and [2,3] I should remove [3,2] (the one which has bigger starting index value.)
Could you help me to fix this?
Here is an example of how you can do it:
function makeUnique(arr) {
var uniques = [];
var itemsFound = {};
arr.sort((a, b) => a[0] + a[1] - (b[0] + b[1]))
for (var i = 0, l = arr.length; i < l; i++) {
if (!itemsFound[arr[i]] && !itemsFound[[arr[i][1], arr[i][1]]]) {
uniques.push(arr[i]);
itemsFound[arr[i]] = true;
itemsFound[[arr[i][1], arr[i][0]]] = true;
}
}
return uniques;
}
I hope it helps.
There are two parts
similar should be considered
among similar, one with smaller first key should stay
1. Similar should be considered
Here you can just make the key for hashmap in such a way that similar items produce same key.
One way to do that is sort the items in the tuple and then form the key, as there are two items only, first one will be min and second one will be max
let a = [
[5, 6],
[1,1],
[6,5],
[1,1],
[3,2],
[2,3]
]
function makeUnique(arr) {
var uniques = [];
var itemsFound = {};
for(var i = 0, l = arr.length; i < l; i++) {
let [a,b] = arr[i];
const hashKey = [ Math.min(a,b), Math.max(a,b)];
var stringified = JSON.stringify(hashKey);
if(itemsFound[stringified]) continue;
uniques.push(arr[i]);
itemsFound[stringified] = true;
}
return uniques;
}
let ans1=makeUnique(a)
console.log(ans1);
2. Among similar, the one with smaller first key should stay
Now you can remember in the hashmap what the value for a key was and keep updating it based on the correct candidate
let a = [
[5, 6],
[1,1],
[6,5],
[1,1],
[3,2],
[2,3]
]
function makeUniqueSmallerFirst(arr) {
var items = {};
for(var i = 0, l = arr.length; i < l; i++) {
let [a,b] = arr[i];
const hashKey = [ Math.min(a,b), Math.max(a,b)];
var stringified = JSON.stringify(hashKey);
if (stringified in items) {
let previous = items[stringified];
if (previous[0] > arr[i][0]) {
items[stringified] = arr[i];
}
} else {
items[stringified] = arr[i] // I am just storing the array because if I see a similar item next time, I can compare if that has first item smaller or not
}
}
return Object.values(items); // this doesn't guarantee output order though
// if you want order as well . you can iterate over input array once more and arrange the items in the preferred order.
}
let ans2=makeUniqueSmallerFirst(a)
console.log(ans2);
UPDATED (More simple and faster example for ES5+):
function makeUnique(arr) {
return new Set(a.map(
arr => JSON.stringify(arr.sort((a, b) => a - b)))
)
}
const m = makeUnique(a)
console.log(m) //
OLD:
This is an example of code that makes a two-dimensional array with arrays of any length unique.
let a = [
[5, 6],
[1, 1],
[6, 5],
[1, 5],
[3, 2],
[2, 3],
[6, 5, 3],
[3, 5, 6]
]
function isUnique(uniqueArray, checkedArray) {
let checked = [...checkedArray];
let unique = [...uniqueArray];
let uniqueValue = 0;
unique.forEach(value => {
if (checked.includes(value)) {
checked.splice(checked.indexOf(value), 1)
} else uniqueValue++;
})
return uniqueValue > 0;
}
function makeUnique(array2d) {
let unique = [array2d[0]]
array2d.forEach(checkedArray => {
if (unique.some(uniqueArray => {
if (checkedArray.length !== uniqueArray.length) return false;
return !isUnique(uniqueArray, checkedArray)
}
)) return 0;
else unique.push(checkedArray)
})
return unique
}
console.log(makeUnique(a)) // [ [ 5, 6 ], [ 1, 1 ], [ 1, 5 ], [ 3, 2 ], [ 6, 5, 3 ] ]
isUnique() this function checks if the numbers in both arrays are unique, and if they are, it outputs true. We use the copy through spread operator, so that when you delete a number from an array, the array from outside is not affected.
makeUnique() function makes the array unique, in the following way:
It checks if our unique two-dimensional array has at least one array that is identical to checkedArray
The first check if the arrays are of different lengths - they are unique, skip and check for uniqueness, if !isUnique gives out true, then the array is skipped by return 0

Modifying an array in a nested loop in a function

I think I'm misunderstanding something about variable scope in JavaScript. The goal is, given an array of numbers, to generate a 2D array that contains all the rotations of that array. So, the array [1,2,3,4] should yield a 2D array of:
[ [1,2,3,4],[2,3,4,1],[3,4,1,2],[2,3,4,1] ]
I'm coming from Ruby, where the following would work just fine:
row = [3,1,6,4];
function rotations(arr) {
var rotations = [];
var i = 0;
var k = arr.length;
while(i < k) {
arr.unshift(arr.pop());
rotations.push(arr);
i++;
};
return rotations;
};
console.log(rotations(row));
However, what this logs is a 2D array containing 4 iterations of the original array:
[ [ 3, 1, 6, 4 ], [ 3, 1, 6, 4 ], [ 3, 1, 6, 4 ], [ 3, 1, 6, 4 ] ]
So it appears that the original array row is not being modified in the scope of the function - only in the scope of the nested while loop.
You just need to copy your array before modifying it with unshift, because it modifies origin array
var row = [3,1,6,4];
function rotations(arr) {
var rotations = [arr];
var i = 1;
var k = arr.length;
var copiedArr = arr
while(i < k) {
copiedArr = [...copiedArr]
copiedArr.unshift(copiedArr.pop());
rotations.push(copiedArr);
i++;
};
return rotations;
};
console.log(rotations(row));
console.log(rotations([1,2,3,4]))
More about unshift is here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift
Or if you need the first element also being rotated
var row = [3,1,6,4];
function rotations(arr) {
var rotations = [];
var i = 0;
var k = arr.length;
var copiedArr = arr
while(i < k) {
copiedArr = [...copiedArr]
copiedArr.unshift(copiedArr.pop());
rotations.push(copiedArr);
i++;
};
return rotations;
};
console.log(rotations(row));
console.log(rotations([1,2,3,4]))

loop push to a new array the numbers in an array

i have the below code that is not working.
var array = [1, 3, 2]
var newArray = []
getNewArray() {
for (let i = 0; i < array.length; i++) {
for (let x = 0; x < array[i]; x++) {
this.newArray.push(array[i]);
}
}
console.log(this.newArray);
}
What i would like to achieve is to use the numbers in a array to loop through the number of times. with the results as shown below
(3) [{…}, {…}, {…}]
0:
count:(1) [1]
1:
count:(3) [1,2,3]
2:
count:(2) [1,2]
Right now it is displaying as
(4) [1, 2, 2, 1]
0: 1
1: 2
2: 2
3: 1
Since you are using ES6 features, you can try a combination of .map + Array.from.
Idea:
Use Array.map and loop over every item.
Use this item as length and create a new array using Array.from.
Pass a mapper function to populate array.
var array = [1, 3, 2];
var result = array.map((item) => Array.from({
length: item
}, (_, i) => i + 1));
console.log(result)
Try this
var array = [1, 3, 2]
var newArray = []
function getNewArray() {
for (let i = 0; i < array.length; i++) {
var tmp = [];
for (let x = 0; x < array[i]; x++) {
tmp.push(x+1);
}
this.newArray.push(tmp);
}
}
getNewArray();
console.log(this.newArray);
var array = [1, 3, 2];
var newArray = [];
function getNewArray() {
for (let i = 0; i < array.length; i++) {
var tempArray = [];
for (let x = 0; x < array[i]; x++) {
tempArray.push(array[i]);
}
newArray.push(tempArray);
}
console.log(this.newArray);
}
getNewArray();
With some array magic
var array = [1, 3, 2]
var newArray = []
let getNewArray = () => {
newArray = array.map( x => Array(x).fill().map( (_,i) => i+1 ) )
console.log(newArray);
}
getNewArray()

How to push elements of a 1d array into a 9x9 array in javascript? [duplicate]

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)

Split array into chunks and sum each index, then merge into another array

I am splitting an array into two arrays arr1 & arr2. Then I want to sum the values and bind into another array like arr3. How can I do this?
var arr1 = [1,2,3,4]
var arr2 = [2,3,4,4]
var arr3 = [3,5,7,8]
this works fine with static arrays, but my problem is
var TotalOfArray = [];
var temparray = [];
for (i = 0, j = x.length; i < j; i += chunk) {
temparray = x.slice(i, i + chunk);
if (temparray.length == chunk) {
console.log("before loop: "+TotalOfArray.length);
if (TotalOfArray.length == 0) {
for (i in temparray) {
TotalOfArray[i] = temparray[i];
}
console.log("after loop: "+TotalOfArray.length);
} else {
for (i in temparray) {
TotalOfArray[i] = TotalOfArray[i] + temparray[i];
}
}
}
}
As you can see, x will be the main array which I am splicing into a temparray array, so every time it will splice with array length 31 and than I want to do sum, chunk = 31 as of now. But it's not going into ELSE part.
Equal Length Arrays:
This is just a more simple version, that assumes equal lengths from both arrays. For a solution that works with variable length arrays, read further on.
var arr1 = [1, 2, 3, 4];
var arr2 = [2, 3, 4, 4];
var arr3 = arr1.map(function(a, i) {
return a + arr2[i];
});
console.log(arr3);
Variable Length Arrays:
This is going to be a more robust solution regardless. But it finds the array with the most values in it, and uses that for the map. Then, if undefined values are found in the other array, it will use 0 as the other number.
var arr1 = [1, 2, 3, 4];
var arr2 = [2, 3, 4, 4, 5];
var sorted = [arr1, arr2].sort((a, b) => b.length - a.length);
var arr3 = sorted[0].map(function(a, i) {
return a + (sorted[1][i] || 0);
});
console.log(arr3);
Use for loop:
var arr1 = [1,2,3,4]
var arr2 = [2,3,4,4]
var arr3 = []
for (i in arr1) { arr3[i] = arr1[i] + arr2[i]; }
console.log(arr3)
If two arrays have equal length you can can use Array.prototype.map();
var data1 = [1,2,3,4],
data2 = [2,3,4,4],
result;
result = data1.map(function(value, i){
return value + data2[i];
});
console.log(result);
var arr1 = [1,2,3,4]
var arr2 = [2,3,4,4]
var arr3 = []
for (var i = 0; i < arr1.length; i++) {
arr3.push(arr1[i] + arr2[i])
}
Assuming arr1 and arr2 have the same length.

Categories