Merge two of one dimensional array into two dimensional array javascript - javascript

I have n (but for now, let say just two) of one dimensional arrays like this image of my console :
And I want to merge these two arrays by the corresponding key and put it into two dimensional array :
The result is something like :
[["1 279 226,08" , "127"],[null , null],["-188 033,77", "154"],..... so on ......]
And the list of one dimensional array is dynamic, it could be more than 2 arrays.
So example if I have 3 arrays, then my two dimensional array would look like :
[ ["1 279 226,08" , "127" , "blabla"], [null , null , "blabla"], ["-188 033,77", "154", "blabla"], ..... so on ......]
Any ideas of implementing it would be appreciate.

You could transpose the array with a nested loop and switch the indices for assigning the values.
var array = [["1 279 226,08", null, "-188 033,77"], ["127", null, "154"], ["blabla", "blabla", "blabla"]],
result = array.reduce(function (r, a, i) {
a.forEach(function (b, j) {
r[j] = r[j] || [];
r[j][i] = b;
});
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Since all of your arrays have the same size, you can loop just on the lenght of the first array, i.e. a.
Then we pass to appendArrays the single value of a , b, ..., and we return the an array to push into merged
var a = ["123", null, "ciao"]
var b = ["321", 1, "pippo"]
var c = ["111", 5, "co"]
var merged = []
for (i = 0; i < a.length; i++) {
merged.push(appendArrays(a[i], b[i], c[i]));
}
console.log(merged);
function appendArrays() {
var temp = []
for (var i = 0; i < arguments.length; i++) {
temp.push(arguments[i]);
}
return temp;
}

This should do what you want.
var arr1 = [1, 2, 3, 4, 5, 6];
var arr2 = [6, 5, 4, 3, 2, 1];
var arr3 = [7, 8, 9, 10, 11, 5];
var arr4 = [12, 34, 55, 77, 22, 426];
var arrCollection = [arr1, arr2, arr3, arr4];
// if array sizes are variable.
// if not max = arrCollection[0].length will do
var max = Math.max.apply(Math, arrCollection.map(function(a) {
return a.length;
}));
var arrFinal = [];
for (let i = 0; i < max; i++) {
var arr = [];
arrCollection.forEach(function(a) {
arr.push(a[i]);
});
arrFinal.push(arr);
}
console.log(arrFinal);

You can create this with two forEach() loops.
var arr1 = [[1, 2], [3, 4], [5, 6]];
var arr2 = [[1, 2, 3], [4, 5, 6], [7, 8], [9, 10, 12, 14]];
let merge = function(arr) {
var result = [];
arr.forEach(function(e, i) {
e.forEach(function(a, j) {
if (!result[j]) result[j] = [a];
else result[j].push(a)
})
});
return result;
}
console.log(JSON.stringify(merge(arr1)))
console.log(JSON.stringify(merge(arr2)))

Related

How to create nested array of different length from a multidimensional array

I have an array that looks like this:
arr = [[1,2,3],
[4,5,6],
[7,8,9]]
I have initialized an empty array and I want put the diagonals of the arr inside the new array. So i've tried this:
arr = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
new_arr = [];
tail = arr.length - 1;
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr[i].length; j++) {
if (j == i) {
new_arr.push(arr[i][j]);
}
if (j == tail) {
new_arr.push(arr[i][j]);
tail--;
}
}
}
console.log(new_arr)
The logic seems to work but I can't seem to get the structure right. What I want is to nest two arrays inside the new array like this:
[[1,5,9],[3,5,7]]
But what I get is one array with the right values unordered. How to get the expected output? Any help is appreciated. Thanks!
You need to have 2 separate temporary arrays. And you don't need nested loops. You can optimize the code like this with a single loop if you understand the math.
arr = [[1,2,3],
[4,5,6],
[7,8,9]];
function findDiagonals(arr) {
const diagonal_1 = [];
const diagonal_2 = [];
for( let i = 0; i < arr.length; i++ ) {
diagonal_1.push(arr[i][i]);
diagonal_2.push(arr[i][arr.length - (i+1)]);
}
return [diagonal_1, diagonal_2];
}
console.log(findDiagonals(arr));
var arr = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
var diagonal1 = [];
var diagonal2 = [];
for (var i = 0; i < arr.length; i++) {
diagonal1.push(arr[i][i]);
diagonal2.push(arr[i][arr.length - i - 1]);
}
var new_arr = [diagonal1, diagonal2];
console.log(new_arr)
The following solution would work for you if the width and height of the number matrix is always equal.
const arr = [[1,2,3],
[4,5,6],
[7,8,9]];
const result = [[],[]];
arr.map((row,index) => {
result[0].push(row[0+index]);
result[1].push(row[row.length - index - 1]);
});
console.log(result); // [[1,5,9],[3,5,7]]
This is a O(n) approach by using the function Array.prototype.reduce.
const arr = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
const result = arr.reduce(([left, right], array, row, {length}) => {
return [[...left, array[row]], [...right, array[length - row - 1]]];
}, [[],[]]);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
the difficulty is low:
const
arr = [[1,2,3],[4,5,6],[7,8,9]]
, new_arr = [[],[]]
;
let p0 = 0, p1 = arr.length
for( let inArr of arr)
{
new_arr[0].push( inArr[p0++] )
new_arr[1].push( inArr[--p1] )
}
console.log( JSON.stringify( new_arr ))
in a one Line code:
const
arr = [[1,2,3],[4,5,6],[7,8,9]]
, new_arr = arr.reduce(([lft,rgt],A,i,{length:Sz})=>([[...lft,A[i]],[...rgt,A[Sz-i-1]]]),[[],[]])
;
console.log( JSON.stringify( new_arr )) // [[1,5,9],[3,5,7]]

Multiplying Two Arrays

I am trying to multiply two arrays, of the same length and create a third array from it.
I've tried loops and I think a nested loop would be the way forward.
Below is my attempt, that multiplied out the whole array
var one = [1, 2, 3, 4, 5];
var two = [1, 2, 3, 4, 5];
//var partOne = one.length
var partOne = []
for(var i=0; i<one.length;i++) {
for(var j=0;j<two.length;j++) {
partOne.push({value:one[i] * two[i]});
}
}
Looking for something similar to the below;
var a = [3, 5]
var b = [5, 5]
//answer
var c = [15, 25]
function multiply(a, b) {
var c = [];
for (var i=0; i<a.length;i++) {
c.push(a[i]*b[i]);
}
return c;
}
var a = [3, 5 ];
var b = [5, 5 ];
var c = multiply(a, b);
console.log(c);
var a = [3, 5 ]
var b = [5, 5 ]
var c = []
for (var i=0; i<a.length;i++) {
c.push(a[i]*b[i]);
}
console.log(c);
let a = [3, 5];
let b = [5, 5];
// x is each element from a
// i is index of a
let c = a.map((x, i) => { return x * b[i]; });
returns
// Array [ 15, 25 ]

How to log only the elements from second level array from a multidimentional array

I have the following array and I need to log only the elements from the second level array from it.
var myArr = [1, 2, 3, [10, 11,[1321,3213,[321321, true], "ha"], 133], 4, 5];
The output should be:
mySecondArr = [10, 11, 133];
with the following code, the output will include the third grade and so on arrays
for(i = 0; i < myArr.length; i++){
if (typeof(myArr[i]) == 'object'){
console.log(myArr[i])
}
}
Thank you in advance!
You can filter by Array.isArray:
const findInnerArr = outerArr => outerArr.find(item => Array.isArray(item));
const myArr = [1, 2, 3, [10, 11,[1321,3213,[321321, true], "ha"], 133], 4, 5];
const output = findInnerArr(myArr)
.filter(item => !Array.isArray(item));
console.log(output);
For more 2nd levels, you could filter by array and filter the inner arrays out and concat the result to a single array.
var array = [1, 2, 3, [10, 11, [1321, 3213, [321321, true], "ha"], 133], ['foo', 'bar', ['baz']], 4, 5],
result = array
.filter(Array.isArray)
.map(a => a.filter(b => !Array.isArray(b)))
.reduce((r, a) => r.concat(a));
console.log(result);
#CertainPerformance answer looks much better, but still for your reference, this is your way.
var newArr = [];
for(i = 0; i < myArr.length; i++){
if (typeof(myArr[i]) == 'object'){
// second level found
for(var j=0;j<myArr[i].length;j++){
if(typeof(myArr[i][j]) != 'object'){
newArr.push(myArr[i][j]);
}
}
break;
}
}
Use Array.filter, Array.reduce and Array.isArray
let myArr = [1, 2, 3, [10, 11,[1321,3213,[321321, true], "ha"], 133], 4, 5, ['this', 'should', ['not'], 'be', 'part', 'of', 'result']];
/* 1. Get all the items that are array from myArr
** 2. Reduce that array with pushing non-Array into the result. */
let result = myArr.filter((a) => Array.isArray(a)).reduce((a,c) => [...a, ...c.filter((d) => !Array.isArray(d))], []);
console.log(result);
Recursive mode get any level of the array
function getElementsAt(_array, level, currentLvl=1){
if(level< 1) throw("level must be > 1");
if(typeof _array === "undefined") throw("Array or level is undefined");
hasSubLvl = _array.some(e=>{
return e instanceof Array;
});
if(currentLvl!== level){
const __array = _array.filter(e =>{
return e instanceof Array;
})[0];
return getElementsAt(__array, level, currentLvl+1);
}
else{
return !hasSubLvl ? _array : _array.filter(e =>{
return !(e instanceof Array);
});
}
}
const arr = [1, 2, 3, [10, 11,[1321,3213,[321321, true], "ha"], 133], 4, 5];
const myArr = getElementsAt(arr, 2);
console.log(myArr, "result");
#CertainPerformance did it in the most cleanest and sweetest way.
I've used for-loops to find your result.
var myArr = [1, 2, 3, [10, 11,[1321,3213,[321321, true], "ha"], 133], 4, 5];
let ans = []
for(let i=0;i<myArr.length; i++) {
if(Array.isArray(myArr[i])) {
for(let j=0;j<myArr[i].length;j++) {
if(!Array.isArray(myArr[i][j])) {
ans.push(myArr[i][j]);
}
}
}
}
console.log(ans);
var myArr = [1, 2, 3, [10, 11,[1321,3213,[321321, true], "ha"], 133], 4, 5];
myArr = myArr.find((data) => typeof(data) ==='object');
myArr = myArr.filter((data) => typeof(data) != 'object');
console.log(myArr);
I've come with a simple solution to my own question, easy to understand for beginers :) thank you all for the help!
var myArr = [1, 2, 3, [10, 11, [1321, 3213, [321321, true], "ha"], 133], 4, 5];
for (i = 0; i < myArr.length; i++) {
if (typeof (myArr[i]) == 'object') {
var secondArr = arrayulMeu[i]
for (j = 0; j < secondArr.length; j++) {
if (typeof (secondArr[j]) != 'object') {
console.log(secondArr[j])
}
}
}
}

Arrays withing an array: how to push all elements forward by one with javascript

This is my array of arrays:
arr_1 = [1,2,3]
arr_2 = [4,5,6]
arr_3 = [7,8,9]
arr = [arr_1, arr_2, arr_3]
arr = [[1,2,3], [4,5,6], [7,8,9]]
What I want to do is push all elements like so that the final array is like the following and insert another element at the beginning of my array:
arr = [[i,1,2], [3,4,5], [6,7,8], [9]]
All sub-arrays must not be more than 3 elements.
Thanks for your help.
You could visit all inner arrays and unshift the leftover values from the previous loop.
var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
chunk = 3,
item = 'x',
i = 0,
temp = [item];
while (i < array.length) {
array[i].unshift(...temp);
temp = array[i].splice(chunk, array[i].length - chunk);
i++;
}
if (temp.length) {
array.push(temp);
}
console.log(array.map(a => a.join(' ')));
You can use the function reduce
var arr = [[1,2,3], [4,5,6], [7,8,9]],
newElem = "newOne",
all = [newElem, ...arr.reduce((a, c) => [...a, ...c], [])], // All together
// Build the desired output asking for the result of:
// element mod 3 === 0
result = all.reduce((a, c, i) => {
if (i % 3 === 0) a.push([c]);
else a[a.length - 1].push(c);
return a;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could move on each iteration last element from previous array to next one and if the last sub-array has more then 3 elements then remove the last one and add it to new array.
let arr_1 = [1, 2, 3],
arr_2 = [4, 5, 6],
arr_3 = [7, 8, 9],
arr = [arr_1, arr_2, arr_3]
setInterval(function() {
const last = arr.length - 1;
const newElement = parseInt(Math.random() * 30)
arr.forEach((a, i) => {
if(i == 0) a.unshift(newElement);
if(arr[i + 1]) arr[i + 1].unshift(a.pop())
else if(arr[last].length > 3) arr[last + 1] = [arr[last].pop()]
})
console.log(JSON.stringify(arr))
}, 1000)
You can do this quite succinctly with a simple unravel/ravel. It easy to adjust group size too.
let arr = [ [1,2,3], [4,5,6], [7,8,9]]
let newEl = 0
let groupSize = 3
var newArr = [];
var unravelled = arr.reduce((a, c) => a.concat(c), [newEl])
while(unravelled.length) newArr.push(unravelled.splice(0,groupSize));
console.log(newArr)
arr_1 = [1, 2, 3]
arr_2 = [4, 5, 6]
arr_3 = [7, 8, 9]
arr = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
function reassignChunk(x) {
// create an array which will be used to store unwrapped values
var newArray = [];
arr.forEach(function(elem) {
newArray.push(...elem); //using spread operator to unwrap values
});
newArray.unshift(x, limit)
var modArray = [];
var m, j, temparray, chunk = 3;
for (m = 0; m < newArray.length; m = m + limit) {
// creatinging new array using slice
modArray.push(newArray.slice(m, m + limit));
}
console.log(modArray)
}
reassignChunk(13, 3)
arr = [[i,1,2], [3,4,5], [6,7,8], [9]]
Assuming all your elements are numbers, you can do it like this:
Prepend i to the array
Flatten the array
Convert the array to a comma-separated string
Split the string into chunks of at most 3 numeric substrings (2 commas)
Convert the chunks back into arrays of numbers
const arr_1 = [1,2,3];
const arr_2 = [4,5,6];
const arr_3 = [7,8,9];
const i = 42;
const result = [i,...arr_1,...arr_2,...arr_3].join()
.match(/(?:[^,]+(,|$)){1,2}[^,]*/g).map( x => x.split(',').map(Number) )
;
console.log( result );
You may do your 2d unshifting simply as follows;
var arr_1 = [1,2,3],
arr_2 = [4,5,6],
arr_3 = [7,8,9],
arr = [arr_1, arr_2, arr_3],
us2d = (a2d,...is) => is.concat(...a2d)
.reduce((r,e,i) => (i%3 ? r[r.length-1].push(e)
: r.push([e]), r), []);
console.log(JSON.stringify(us2d(arr,0)));
console.log(JSON.stringify(us2d(arr,-2,-1,0)));

Iterating over rows of 2-dimensional array containing arrays of different length

I have a function that picks all elements from a 2-dimensional array by its rows and returns a 1-dimensional array.
The array has a variable amount of columns and rows.
Example:
let arr = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
];
Returns:
[1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12]
The function i came up with:
convertList = (list) => {
let result = [];
let listTotalEntries = R.sum(R.map(R.length)(list));
let mod = R.modulo(R.__, list.length);
let counterRow = -1;
for (let i = 0; i < listTotalEntries; i++) {
if (mod(i) === 0) {
counterRow++;
}
if (list[mod(i)][counterRow]) {
result.push(list[mod(i)][counterRow]);
console.log(list[mod(i)][counterRow]);
}
}
console.log(result);
return result;
};
Question: This function works only with square matrices - how can i make it work with a variable length of the contained arrays?
Example:
let arr = [
[1, 2],
[],
[9, 10, 11, 12]
];
Should return:
[1, 9, 2, 10, 11, 12]
Thanks for your help!
Muff
You had a ramda.js tag in here. With Ramda, it's pretty simple, since there are two functions that will help:
const convertList = compose(flatten, transpose);
convertList(arr); //=> [1, 9, 2, 10, 11, 12]
transpose flips a matrix over its main diagonal, that is, changing rows to columns and vice versa. flatten turns a list of lists into a plain list. So composeing like this essentially creates the equivalent of list => flatten(transpose(list)).
You can see this in action on the Ramda REPL.
I suggest to go step-by-step through the arrays
var arr1 = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]],
arr2 = [[1, 2], [], [9, 10, 11, 12]];
function single(array) {
var r = [],
max = Math.max.apply(null, array.map(function (a) { return a.length; })),
i = 0, j,
l = array.length;
while (i < max) {
for (j = 0; j < l ; j++) {
i in array[j] && r.push(array[j][i]);
}
i++;
}
return r;
}
document.write('<pre>' + JSON.stringify(single(arr1), 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(single(arr2), 0, 4) + '</pre>');
Did you try this simple one?
var singleDimensionArr = arr.reduce(function(prev,current){return prev.concat(current)});
For example
[
[1, 2],
[],
[9, 10, 11, 12]
].reduce(function(prev,current){return prev.concat(current)});
outputs [1, 2, 9, 10, 11, 12]
Edit:
Based on the inputs from OP below, since the concatenation needs to happen column wise
var max = Math.max.apply(null, arr.map(function (a) { return a.length; }));
var finalArr = []; for( var i = 0; i < max; i++)
{
for( var j = 0; j < arr.length; j++)
{
arr[j][i] ? finalArr.push(arr[j][i]) : "";
}
}
console.log(arr);
This example makes a big sparse array putting each item where it would belong if the array were square. Then it filters out null values which occur where no input item was present.
let arr = [
[1, 2],
[],
[9, 10, 11, 12]
];
var out = arr.reduce(function(o,n,i,a) {
for (var j=0;j<n.length;j++){
o[a.length * j + i] = n[j];
}
return o;
},[]).filter(function(n) {
return n !== null;
});
alert(JSON.stringify(out));

Categories

Resources