I am just learning javascript.I am pretty confused with manipulating multidimensional arrays.
var myarr = [
[ 7, 9, 10 ],
[ 6, 9 ],
[ 5, 9 ]
]
I want to insert zero like this.What is the smart way to do this in javascript
[
[ 7, 9, 10 ],
[ 6, 9, 0 ],
[ 5, 9, 0 ]
]
You could get first the max length of the inner arrays and push zeroes until all inner arrays have the same length.
var myarr = [[7, 9, 10], [6, 9], [5, 9]],
length = myarr.reduce(function (r, a) { return Math.max(r, a.length); }, 0);
myarr.forEach(function (a) {
while (a.length < length) {
a.push(0);
};
});
console.log(myarr);
.as-console-wrapper { max-height: 100% !important; top: 0; }
var myarr = [
[ 7, 9, 10 ],
[ 6, 9 ],
[ 5, 9 ]
]
for(var i = 0; i < myarr.length; i++) {
if(myarr[i].length < myarr.length){
myarr[i].push(0);
}
}
console.log(myarr);
Here is a solution.
var myarr = [
[7, 9, 10],
[6, 9],
[5, 9]
];
var rows = myarr.length;
var cols = 0;
for (var i in myarr) {
if (myarr[i].length > cols)
cols = myarr[i].length;
}
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
if (myarr[i][j] == undefined)
myarr[i][j] = 0;
}
}
console.log(myarr);
Best way would be first to calculate what the longest sub-array length you have, then you can pad the sub-arrays to make them all up to the same length.
The following includes a function for calculating the longest length, and another for performing the padding:
function getMax(arr) {
var max = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i].length > max)
max = arr[i].length;
}
return max;
}
function pad(arr, max) {
for (var i = 0; i < arr.length; i++) {
for (var j = arr[i].length; j < max; j++)
arr[i].push(0);
}
}
var myarr = [
[7, 9, 10],
[6, 9],
[5, 9]
];
pad(myarr, getMax(myarr));
console.log(myarr);
Seems like you need a square matrix from a 2 dimension array, so try this:
var myarr = [
[7, 9, 10],
[6, 9],
[5, 9, 1, 2, 3, 4, 5, 6, 7] // <--- for example purpose
];
var rows = myarr.length;
var cols = 0;
for(var i = 0; i < myarr.length; i++){
if(myarr[i].length > cols)
cols = myarr[i].length;
}
var limit = rows > cols ? rows : cols;
for(var i = 0; i < limit; i++){
if(myarr[i] == undefined)
myarr[i] = new Array(limit);
for(var j = 0; j < limit; j++){
if(typeof myarr[i][j] == "undefined")
myarr[i][j] = 0;
}
}
for(var i = 0; i < limit; i++){
console.log(JSON.stringify(myarr[i]));
}
var maxLength=0;
for(var i=0;i<myarr.length;i++){
if(myarr[i].length>maxLength){
maxLength=myarr[i].length
}
}
for(var i=0;i<myarr.length;i++){
if(myarr[i].length!=maxLength){
fillZeros(myarr[i])
}
}
function fillZeros(child){
while(child.length!=maxLength)
{child.push(0);}
}
If your array is a numbers only arbitrarily nested filled array, you could use a recursive function like I have here:
function fillArray(array, val){
for(var i=0; i<array.length; i++){
if(typeof(array[i]) === 'number'){
array[i] = val;
}else{
fillArray(array[i], val);
}
}
}
var test = [5,[3,8,-1,[3,4,5,2,1],[2] ],[[2,2],[3]],[[2,3],[4]],[[2,4],[5]]];
fillArray(test, 0);
using map function
var arr = [
[ 7, 9, 10 ],
[ 6, 9],
[ 5, 9]
]
var arr1 = arr.map(function(e){
var arr2 = [];
if(e.length < 3)
e.push(0);
arr2.push(e);
return arr2;
});
alert(arr1);
Related
I am trying to write a function that will take an array and n as parameters,
it will return all subsets of that array with n elements, have tried a couple things, couldn't yet succeed.
thanks to whoever put it here, this functions is way too complicated and doesn't do the job, basically what I tried to do here is to pick out one element from a 4 element array to create its 3 element subsets. It doesn't even take N as parameter. it returns all 3 element subsets but also identical ones, so I have to filter them out as well, in any case I will keep trying.
function findSubsets(array) {
var answers = [];
var firstArray = array;
for (i = 0; i < array.length; i++) {
array = firstArray;
for (var k = 0; k < array.length; k++) {
if (k != i) {
var subset = array.splice(k, 1);
answers.push(array); array.splice(k, 0, subset[0]);
}
}
}
}
That not as complicated as it seems. This one is optimized because it doesn't creates useless temporary arrays during the process.
function findSubsets(array, n) {
var answers = [];
for(var i = 0 ; i < array.length ; i += n) {
answers.push(array.slice(i, i + n));
}
return answers;
}
findSubsets([1, 2, 3, 4, 5, 6, 7, 8, 9], 2) // --> [[1, 2], [3, 4], [5, 6], [7, 8], [9]]
findSubsets([1, 2, 3, 4, 5, 6, 7, 8, 9], 3) // --> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
You can try this solution
var subsetArray = (function() {
return {
getResult: getResult
}
function getResult(array, n) {
function isBigEnough(value) {
return value.length === n;
}
var ps = [
[]
];
for (var i = 0; i < array.length; i++) {
for (var j = 0, len = ps.length; j < len; j++) {
ps.push(ps[j].concat(array[i]));
}
}
return ps.filter(isBigEnough);
}
})();
var arr = [1, 2, 3, 4,5,6,7,8,9];
console.log(subsetArray.getResult(arr,2));
how do loop through this 3x3 grid of arrays horizontally and print out 1, 4, 7, 2, 5, 8, 3, 6, 9?
edit: is there a more efficient way of doing this other than to use a two loops that also works if the length of the arrays are not equal to the other ones?
let grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
You can use nested for Loops:
let grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
];
for(let i = 0; i < grid[0].length; i++){
for(let j = 0; j < grid.length; j++)
console.log(grid[j][i]);
}
You have a lot of answers that work if the arrays are all the same length. Here's a way to handle potentially different length arrays. It basically runs until it can't find any more data:
let grid = [
[1, 2, 3, 4, 5],
[4, 5, 6, 7],
[7, 8, 9, 10, 11, 12]
];
let current = grid, i = 0
while(current.length){
current = grid.filter(arr => i < arr.length)
current.forEach(arr => console.log(arr[i]))
i++
}
for(var i = 0; i < grid.length; i++) {
var arr = grid[i];
for(var j = 0; j < arr.length; j++) {
console.log("array[" + i + "][" + j + "] = " + arr[j]);
}
}
you just have to find the sizes of the inner array and outer array
for(let i=0;i<countYourArraySize;i++)
{
for(let j=0;j<countYourInnerArayLength;j++)
{
console.log(grid[j][i])
}
}
let grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
let gridLength = grid[0].length;
let gridHeight = grid.length;
for(let l1=0; l1<gridLength;l1++) {
for(let l2=0; l2<gridHeight;l2++) {
console.log(grid[l2][l1]);
}
}
Assuming grid is rectangular(and grids usually are ;)), you can loop through it, columns first, rows second like in this snippet.
There was a question if we can do it without 2 loops, we can and I think its actually better and cleaner solution:
let grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
let gridLength = 3;
for(let l1=0; l1<gridLength*gridLength;l1++) {
console.log(grid[l1%gridLength][Math.floor(l1/gridLength)]);
}
You can do it with just one (explicit) loop if you use map:
let grid = [
[1,2,3],
[4,5,6],
[7,8,9]
];
let result = [];
for (let i=0; i < grid.length; i++) {
result = result.concat(grid.map((row) => row[i])));
}
console.log(result);
You can do this in a single loop. But the length must same for this
let grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
for (var i = 0; i < grid.length*grid.length; i++) {
var row = Math.floor(i / grid.length);
var col = i % grid.length;
console.log(grid[col][row]);
}
You need to make use of a nested for loop:
So please have a look at my solution:
let grid = [
[1,2,3],
[4,5,6],
[7,8,9]
];
for (let x = 0; x < grid[0].length; x++) {
for (let y = 0; y < grid.length; y++) {
console.log(grid[y][x]);
}
}
This grid prints out the expected solution: 1, 4, 7, 2, 5, 8, 3, 6, 9?
Some explanation:
In this case we are using two different for-loops.
the outer one for the X for (let x = 0; x < 3; x++) {}
the inner one for the Y for (let y = 0; y < 3; x++) {}
Note: This will just work if the grid is rectangular because using grid[0].length will otherwise produce an error.
Edit: If you just want to use a single loop try something like this:
let grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
for (let i = 0 ; i < grid.length * grid[0].length ; i++)
console.log(grid[i % grid.length][parseInt(i / grid.length)]);
I have a multidimensional array that returns undefined after the last value of every sub-array. Here is my code:
var bigArray = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]
];
for (i = 0; i < bigArray.length; i++) {
for (j = 0; j <= bigArray[i].length; j++) {
console.log(bigArray[i][j]);
}
}
Remove the = part from the condition of the second loop. You tries to access an element out of the range of the array. Also declare your variables with var, let or const - in the case with i and j.
var bigArray = [
[1,2,3],
[4,5,6],
[7,8,9],
[10,11,12]
];
for(var i = 0; i < bigArray.length; i++) {
for(var j = 0; j < bigArray[i].length; j++) {
console.log(bigArray[i][j]);
}
}
In this case, '.length' method will return the total number elements in that array, But array index starts from 0. So if an array contains n elements the array index of the last element will be n-1. And if you are trying to access an array with index n it will return an ArrayIndexOutOfBound Exception.
You can try this code
var bigArray = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]
];
for (i = 0; i <= bigArray.length-1; i++) {
for (j = 0; j <= bigArray[i].length-1; j++) {
console.log(bigArray[i][j]);
}
}
How to create a chunks of array by part base on given parts count..
for example ..
var myarray = [1,2,3,4,5,6,7,8,9,10];
var bypart = 3 ;
makechunks(bypart);
expected output is ..
[1,2,3],[4,5,6],[7,8,9,10]
from large array to 3 small arrays
There is no built in way in either javascript or angular.
I assume you want all parts to be roughly the same size.
function splitArray(array, groups) {
var sets = [];
var groupsize = array.length / groups;
for (var i = 0, j = 0; i < groups; i++, j += groupsize) {
sets[i] = array.slice(j, j + groupsize);
}
return sets;
}
For your given input splitArray([1,2,3,4,5,6,7,8,9,10], 3) the result will be [[1,2,3],[4,5,6],[7,8,9,10]]
You could use only a fraction of the length and add it to the index.
function chunk(array, count) {
var result = [],
size = array.length / count;
i = 0;
while (i < array.length) {
result.push(array.slice(i, i += size));
}
return result;
}
console.log(chunk([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3));
console.log(chunk([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], 3));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Did you try to google?
Here is what you need:
var createGroupedArray = function(arr, chunkSize) {
var groups = [], i;
for (i = 0; i < arr.length; i += chunkSize) {
groups.push(arr.slice(i, i + chunkSize));
}
return groups;
}
Usage example:
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
var groupedArr = createGroupedArray(arr, 4);
var result = JSON.stringify(groupedArr);
// result: "[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14]]"
Taken from:
http://www.frontcoded.com/splitting-javascript-array-into-chunks.html
UPDATED:
var makechunks = function(arr, chunksAmount) {
var chunkSize = Math.ceil(arr.length/chunksAmount);
var groups = [], i;
for (i = 0; i < arr.length; i += chunkSize) {
groups.push(arr.slice(i, i + chunkSize));
}
return groups;
}
What is a fast way to find combinations that aren't present in an array yet?
E.g, I have list of points: [1, 2, 4, 9]
And I have a list of connections [[1,2], [1,4], [1,9], [2,4], [4,9]]
So the missing connection in this list is [2,9]. As there is one requirement: every integer must be connected to a bigger integer.
var points = [1, 2, 4, 9];
var connections = [[1,2], [1,4], [1,9], [2,4], [4,9]];
var missing = [];
for(i = 0; i < points.length; i++){
for(j = i + 1; j < points.length; j++){
var found = false;
for(var a = 0; a < connections.length; a++){
if(connections[a][0] == points[i] && connections[a][1] == points[j]){
found = true;
break;
}
}
if(!found) missing.push([points[i], points[j]]);
}
}
console.log(missing);
The above code works, but the amount of for loops makes me think it is reasonably slow. Is there any faster way to do this? View jsfiddle
By sorting the array, you can do it with 2 nests. Sorting takes O(n log n), and the loops are basically O(n ^ 2).
var points = [1, 2, 4, 9];
var connections = [
[1, 2],
[1, 4],
[1, 9],
[2, 4],
[4, 9]
];
connections.sort();
var missing = [];
var currentIndex = 0;
for (var i = 0; i < points.length; i++) {
for (var j = i + 1; j < points.length; j++) {
if (connections[currentIndex][0] == points[i] && connections[currentIndex][1] == points[j]) {
currentIndex++;
} else {
missing.push([points[i], points[j]]);
}
}
}
console.log(missing);
You can use .reduce method in order to generate all the combination of two elements.Then the only thing that will remain is to get the difference from two arrays.
For this, you can use filter method which accepts a callback method.
var points = [1, 2, 4, 9];
points=points.sort();
var connections = [[1,2], [1,4], [1,9], [2,4], [4,9]];
var combinations = points.reduce(function(arr,elem,i){
for(j=i+1;j<points.length;j++)
arr.push([elem,points[j]]);
return arr;
},[]);
var diff=combinations.filter(function(elem,i){
return connections.find(a=>a[0]==elem[0] && a[1]==elem[1])==undefined;
});
console.log(diff);
You could iterate only the outer loop until length - 2 and use a hash table for inserted connections. The sort order of connections does not matter.
var points = [1, 2, 4, 9],
connections = [[1, 2], [1, 4], [1, 9], [2, 4], [4, 9]],
missing = [],
i, j,
pair,
connected = Object.create(null);
connections.forEach(function (a) {
connected[a.join()] = true;
});
for (i = 0; i < points.length - 1; i++) {
for (j = i + 1; j < points.length; j++) {
pair = [points[i], points[j]];
connected[pair.join()] || missing.push(pair);
}
}
console.log(missing);
.as-console-wrapper { max-height: 100% !important; top: 0; }