issue with merge sorted arrays problem using javascript - javascript

I am trying to solve merge 2 sorted arrays problem using javascript. Please find my solution below:
input:
const arr1 = [1, 4, 7, 8, 10];
const arr2 = [2, 3, 9];
output:
[1, 2, 3, 4, 7, 8, 9 10]
const arr1 = [1, 4, 7, 8, 10];
const arr2 = [2, 3, 9];
let arrayItem1 = arr1[0];
let arrayItem2 = arr2[0];
let i = 1;
let j = 1;
let mergedArray = [];
while(arrayItem2 || arrayItem1) {
arrayItem1 = arrayItem1 === undefined ? 0 : arrayItem1;
arrayItem2 = arrayItem2 === undefined ? 0 : arrayItem2;
if (arrayItem1 < arrayItem2) {
console.log('inside if');
console.log("first array", arrayItem1);
arrayItem1 = arr1[i];
i++;
mergedArray.push(arrayItem1);
} else {
console.log('inside else');
console.log("second array", arrayItem2);
arrayItem2 = arr2[j];
j++;
mergedArray.push(arrayItem2);
}
console.log("== merged array ==", mergedArray);
}
But it is going in infinite loop. Not sure where I am going wrong. Need a watchful pair of eyes here.
thanks

You need to check the index with the lengths of the arrays and add a final check for getting the rest of the arrays added to the merged array.
const
array1 = [1, 4, 7, 8, 10],
array2 = [2, 3, 9],
mergedArray = [];
let i = 0,
j = 0;
while (i < array1.length && j < array2.length) {
if (array1[i] < array2[j]) {
mergedArray.push(array1[i++]);
} else {
mergedArray.push(array2[j++]);
}
}
if (i < array1.length) mergedArray.push(...array1.slice(i));
if (j < array2.length) mergedArray.push(...array2.slice(j));
console.log(...mergedArray);

const arr1 = [1, 4, 7, 8, 10];
const arr2 = [2, 3, 9];
const mergedArrays = [...arr1, ...arr2];
// WITH SORT
const result = mergedArrays.sort((a, b) => Number(a) - Number(b));
console.log(result);
// WITHOUT SORT
const bubbleSort = (arr) => {
let done = false;
while (!done) {
done = true;
arr.forEach((el, i) => {
if (arr[i - 1] > arr[i]) {
done = false;
const tmp = arr[i - 1];
arr[i - 1] = arr[i];
arr[i] = tmp;
}
});
}
return arr;
};
const result2 = bubbleSort(mergedArrays)
console.log(result2)
You don't really need to go through all that trouble, you can merge your arrays by destructuring your arrays in new one and just use the Array.sort() method.
UPDATE:
Added sorting without using using Array.sort(), using a sorting algorithm Bubble sort

This will also work for non positive numbers
//[1, 2, 3, 4, 7, 8, 9 10]
const arr1 = [1, 4, 7, 8, 10];
const arr2 = [2, 3, 9];
let arrayItem1 = arr1[0];
let arrayItem2 = arr2[0];
let i = 1;
let j = 1;
let mergedArray = [];
while(arrayItem2 !== undefined || arrayItem1 !== undefined) {
if (arrayItem2 === undefined || arrayItem1 < arrayItem2) {
mergedArray.push(arrayItem1);
arrayItem1 = arr1[i];
i++;
} else {
mergedArray.push(arrayItem2);
arrayItem2 = arr2[j];
j++;
}
console.log('Merged array: ' + mergedArray)
}

Some issues:
The actions in the if block (and else block) occur in the wrong order. You first want to push the item, then increment the index, and then get the next value from the array so it will be used in the next comparison.
Don't assign the value 0 when a value is undefined. Just leave it undefined, otherwise you risk to push a 0 into the result that was never there in the input.
So:
const arr1 = [1, 4, 7, 8, 10];
const arr2 = [2, 3, 9];
let arrayItem1 = arr1[0];
let arrayItem2 = arr2[0];
let i = 1;
let j = 1;
let mergedArray = [];
while(arrayItem2 || arrayItem1) {
if (arrayItem2 === undefined || arrayItem1 < arrayItem2) {
mergedArray.push(arrayItem1);
i++;
arrayItem1 = arr1[i];
} else {
mergedArray.push(arrayItem2);
j++;
arrayItem2 = arr2[j];
}
}
console.log("== merged array ==", mergedArray);

const arr1 = [1, 4, 7, 8, 10];
const arr2 = [2, 3, 9];
var children = arr1.concat(arr2);
console.log (children.sort(function(a, b){return a - b}));
children.sort(function(a, b){return a - b});
const arr1 = [1, 4, 7, 8, 10];
const arr2 = [2, 3, 9];
var children = arr1.concat(arr2);
console.log (children.sort(function(a, b){return a - b}));

Related

i want to do sum of two arrays ,and the sum have to start calculate values from right to left for both the arrays

i want to sum of two arrays where if my first array has 2 elements and 2nd array has 4 elements so the problem is it is sum the starting elements of both arrays,, but i want the
sum should be start calculating from right to left for both the arrays and if the value of each element is suppose 11 so it should remain the last 1 and the first 1 should go up with next element calculation such as my expected result is 1234+5678=6912 in new array = [6,9,1,2]
here is my code-
const Arr1 = [1, 2, 3, 4];
const Arr2 = [5, 6, 7, 8];
function sumArr(A1, A2) {
let A3 = [];
for (let i = 0; i < Math.max(A1.length , A2.length); i++) {
A3.push((A1[i] || 0) + (A2[i] || 0));
}
return A3;
}
console.log(sumArr(Arr1, Arr2))
I'm not sure if I got the question right
But here a more generic function that I hope does what you are expecting to
const Arr1 = [1, 2, 3, 4];
const Arr2 = [5, 6, 7, 8];
const Arr3 = [9, 10]
//more general with
const sumArray = (...arr) => {
const length = Math.max(...arr.map(a => a.length))
return Array(length)
.fill(0)
.map((_, i) => {
return arr.reduce((sum, a) => sum + (a[i] || 0) , 0)
})
}
console.log(sumArray(Arr1, Arr2))
console.log(sumArray(Arr1, Arr3))
console.log(sumArray(Arr1, Arr2, Arr3))
Here a different version based on #RenauldC5 response
const Arr1 = [1, 2, 3, 4];
const Arr2 = [5, 6, 7, 8];
const Arr3 = [9, 10]
//more general with
const sumArray = (...arr) =>
arr.reduce((res, a) => res + parseInt(a.join('')), 0)
.toString()
.split('')
.map(n => parseInt(n))
console.log(sumArray(Arr1, Arr2))
console.log(sumArray(Arr1, Arr3))
console.log(sumArray(Arr1, Arr2, Arr3))
I guess the right approach would be to
Change array to number
Do the classic sum
Split the number into array
const Arr1 = [1, 2, 3, 4];
const Arr2 = [5, 6, 7, 8];
const num1 = parseInt(Arr1.join(''))
const num2 = parseInt(Arr2.join(''))
const total = num1 + num2
const Arr3 = total.toString().split('').map(x => parseInt(x))
console.log(Arr3)
This would work, but both the array should have same number of elements. If your array length is not equal, you can add 0 for the empty space and this code will work on that too.
const a1 = [1, 2, 3, 4]
const a2 = [5, 6, 7, 8]
let carry = 0
const sum = []
for(let i = a1.length-1; i >= 0; i--){
let num = a1[i] + a2[i] + carry
let numArr = num.toString().split('')
if(numArr.length > 1){
carry = Number(numArr[0])
sum.push(Number(numArr[1]))
} else{
carry = 0
sum.push(Number(numArr[0]))
}
}
sum.reverse()
console.log(sum)

Trying to merge two unsorted arrays in Javascript

I have written code in javascript trying to return a single sorted array by giving two sortedarray inputs.
function finalArray(arr1, arr2) {
const mergedArray = [];
if (arr1.length === 0) {
return arr2;
}
if (arr2.length === 0) {
return arr1;
}
let arr1Item = arr1[0];
let arr2Item = arr2[0];
let i = 1;
let j = 1;
while (arr1Item || arr2Item) {
if (arr2Item === undefined || arr1Item < arr2Item) {
mergedArray.push(arr1Item);
arr1Item = arr1[i];
i++;
} else {
mergedArray.push(arr2Item);
arr2Item = arr2[j];
j++;
}
}
return mergedArray
}
console.log(finalArray([2, 6, 4, 10], [15, 1, 5, 33]));
Can anyone help with how to merge unsorted arrays?
Merge your two arrays first, then perform the sort?
const arr1 = [2, 6, 4, 10];
const arr2 = [10, 1, 5, 33];
const newArray = ([...arr1, ...arr2]);
newArray.sort(function(a,b){return a - b});
console.log(newArray);
Expected output: [1, 2, 4, 5, 6, 10, 10, 33]
The problem is you are comparing every two pair of data and pushing smaller one.
First try to sort each sub array without entering compare process for mixing.
After the sub arrays are being sorted, then compare to each other.

JS - Sum Of Two Arrays where arrays can be of unequal length

I need function like this.
function sum(arr1, arr2) {
return totalArray
};
sum([1,2,3,4], [5,6,7,8,9]) // [6,8,10,12,9]
I tried it this way:
var array1 = [1, 2, 3, 4];
var array2 = [5, 6, 7, 8, 100];
var sum = array1.map((num, idx) => num + array2[idx]); // [6,8,10,12]
First you can get an array out of the function's arguments using Spread syntax (...), then sort it by array's length using Array.prototype.sort() and finally Array.prototype.reduce() to get the result array
Code:
const sum =(...arrays) => arrays
.sort((a, b) => b.length - a.length)
.reduce((a, c) => a.map((n, i) => n + (c[i] || 0)) || c)
// two arrays
const resultTwoArrays = sum([1, 2, 3, 4], [5, 6, 7, 8, 9])
console.log(resultTwoArrays) // [6, 8, 10, 12, 9]
// three arrays or more...
const resultThreeArrays = sum([1, 2, 3, 4], [5, 6, 7, 8, 9], [1, 2])
console.log(resultThreeArrays) // [7, 10, 10, 12, 9]
.as-console-wrapper { max-height: 100% !important; top: 0; }
At the risk of being unpopular due to using a loop:
function sum(arr1, arr2) {
let totalArray = [];
const totalLength = Math.max(arr1.length, arr2.length);
for (let i = 0; i < totalLength; i++) {
totalArray[i] = (arr1[i] || 0) + (arr2[i] || 0);
}
return totalArray;
}
The || 0 handles the possibility the array doesn't have an entry at i, because if it doesn't, the result of arrX[i] is undefined, and undefined || 0 is 0.
I try this way.
var array1 = [1, 2, 3, 4];
var array2 = [5, 6, 7, 8, 100];
var sum = array1.map((num, idx) => num + array2[idx]); // [6,8,10,12]
Very close, but map will stop at the end of array1, so you won't get the subsequent entries from array2. Just pick the longer of the two arrays, then handle the fact that the other array may not have an entry at arrayX[idx]. You can do that with the || 0 idiom:
function sum(array1, array2) {
var a, b;
if (array1.length > array2.length) {
a = array1;
b = array2;
} else {
a = array2;
b = array1;
}
return a.map((num, idx) => num + (b[idx] || 0));
}
console.log(sum([1, 2, 3, 4], [5, 6, 7, 8, 100]));
Alternately, you can use the new (but polyfill-able) Array.from to create the result array and use the callback to build the entries:
function sum(array1, array2) {
return Array.from(
{length: Math.max(array1.length, array2.length)},
(_, i) => (array1[i] || 0) + (array2[i] || 0)
);
}
console.log(sum([1, 2, 3, 4], [5, 6, 7, 8, 100]));
Mosho's answer is wonderfully simple, though.
Find the long and short array according to length. Iterate the short array with Array.map(), and take the value from the long array. Then add the leftovers from the long array using Array.slice(), and Array.concat():
function sum(arr1, arr2) {
const [l, s] = arr1.length >= arr2.length ? [arr1, arr2] : [arr2, arr1];
return s.map((n, i) => n + l[i])
.concat(l.slice(s.length));
};
console.log(sum([1,2,3,4], [5,6,7,8,9]));
Are we code golfing this? Here's a generator solution.
const summer = function*(a, b, i=0) {
while(i < a.length || i < b.length) yield (a[i] || 0) + (b[i++] || 0);
};
const sum = (a, b) => [...summer(a,b)];
console.log(sum([1,2,3,4], [5,6,7,8,9])) // [6,8,10,12,9]
You can have a custom logic something like this:
function sum(arr1, arr2) {
var length, selectedArray, nonSelectedArray;
if(arr1.length>arr2.length){
length = arr1.length;
selectedArray = arr2;
nonSelectedArray = arr1;
}else {
length = arr2.length;
selectedArray = arr1;
nonSelectedArray = arr2;
}
var totalArray = [];
for(var i=0; i<length; i++){
if(selectedArray[i]){
totalArray.push(selectedArray[i] + nonSelectedArray[i]);
} else {
totalArray.push(nonSelectedArray[i]);
}
}
return totalArray
};
var res = sum([1,2,3,4], [5,6,7,8,9]);
console.log(res);
Try with map():
function sum(arr1, arr2) {
var [a1, a2] = arr1.length > arr2.length ? [arr1, arr2] : [arr2, arr1]
var totalArray = a1.map(function(i, idx){
i = (i + a2[idx] || i + 0);
return i;
})
return totalArray;
};
console.log(sum([1,2,3,4], [5,6,7,8,9])) // [6,8,10,12,9]

Sorting an array by chunks of 3

Assume that you have an array and want to divide it by chunks of 3. If the array is..
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
...the new array would be
let newArr = [1, 4, 7, 10, 13, 2, 5, 8, 11, 3, 6, 9, 12]
// In other words:
1 2 3
4 5 6
7 8 9
10 11 12
13
The chunking part should be this code (if sorted like newArr):
let chunkedArr = _.chunk(_.toArray(newArr), 3);
...however I couldn't figure out how to sort the arr to newArr to be able to chunk in the right order. What is the proper way of handling such case?
Please note that the integers are just pseudo and I will use proper objects of array.
One option is to use ES6 reduce to group the array into a multidimensional array. Use concat to flatten the multidimensional array.
[].concat(...) - basically flattens the multidimensional array. Starting with an empty array [], you concat each secondary array. Use the spread operator (...) to reiterate each secondary array and concat each.
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
let groups = 3;
let newArr = [].concat(...arr.reduce((c, v, i) => {
let k = i % groups;
c[k] = c[k] || [];
c[k].push(v);
return c;
}, []));
console.log(newArr);
Please try the following (jsfiddle):
//This version works for variable chunk sizes as well.
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
alert(chunks(arr, 3)); //You can update chunk size here
function chunks(arr, chunkSize) {
var result = [];
var index = 0;
for (var i = 0; i < chunkSize; i++) {
for (var j = 0; j < arr.length / chunkSize; j++) {
if (arr[i + (chunkSize * j)] != null)
result[index++] = arr[i + (chunkSize * j)];
}
}
return result;
}
//This version only works for chunks of size 3.
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
let subArr1 = [];
let subArr2 = [];
let subArr3 = [];
var result = [];
var i = 0, j = 0, k = 0;
for (var index = 0; index < arr.length; index++) {
if (index % 3 == 0) {
subArr1[i++] = arr[index];
}
if (index % 3 == 1) {
subArr2[j++] = arr[index];
}
if (index % 3 == 2) {
subArr3[k++] = arr[index];
}
}
result.push(subArr1, subArr2, subArr3);
alert(result);
Please check this it may help you. I also take a reference from here. Please check and let us know. any thing else you need.
Thanks
Here is the sample code.
var i,j,resArr,chunkSize = 10;
for (i=0,j=array.length; i<j; i+=chunk) {
resArr = array.slice(i,i+chunk);
}
const original = [1,2,3,4,5,6,7,8,9,10,11,12,13]
const chunks = 3
function getChunckedArr(arr, n) {
let sub = new Array(n);
let result = [];
for (let i=0; i<sub.length; i++)
sub[i] = []
arr.forEach(function (val, index){
let o = (index % n);
sub[o][sub[o].length] = val;
});
for (let i=0; i<sub.length; i++)
result.push.apply(result, sub[i]);
return result;
}
const chunked = getChunckedArr(original, chunks);

How to iterate the contents of one array into the empty/undefined spots of another array?

I have an array:
var myArray = [2, 4, 6];
and another array:
var otherArray = [1, , 3, , 5, , 7];
I'm trying to map (or use any non "for/for-each" iterator) to place each myArray value into the corresponding empty spaces of otherArray.
Hopeful output:
newArray = [1, 2, 3, 4, 5, 6, 7];
Any ideas?
otherArray.forEach(function (val, idx) {
if (typeof val === 'undefined') {
otherArray[idx] = myArray.shift();
}
});
forEach may not be compatible if supporting IE < 9 though.
Using Array.prototype.map:
var newArray = otherArray.map(function(val) {
return typeof val === 'undefined' ? myArray.shift() : val;
});
Be aware that this will not hit indexes that have never been set.
Using while loop:
while (myArray.length > 0) {
var emptyIdx = otherArray.indexOf();
otherArray[emptyIdx] = myArray.shift();
}
Edit: Ok, if the elements in the array are truly not set, as they are in your description, these solutions won't work since they'll skip over the unset indexes. Here's one that would work:
var myArray = [2, 4, 6, 8, 9];
var otherArray = [1, , 3, , 5, , 7];
var lastIdx = -1;
otherArray.forEach(function(val, idx) {
if (idx - lastIdx > 1) {
otherArray[idx - 1] = myArray.shift();
}
});
if (myArray.length > 0) {
otherArray = otherArray.concat(myArray);
}
document.body.innerHTML = otherArray;
You can iterate through the array and check for undefined values like:
var otherArray = [1, , 3, , 5, , 7];
var myArray = [2, 4, 6];
for (var i = 0, j = 0; i < otherArray.length; i++) {
//check if a value is undefined
if (!otherArray[i]) {
//then change this value with the new from other array
otherArray[i] = myArray[j];
j++;
}
}
console.log(otherArray);//prints [1, 2, 3, 4, 5, 6, 7]
You could use recursivity, this function will fill the undefined items of the first array with the items of the second one until it reach the end of one of the arrays used.
var otherArray = [1, , 3, , 5, , 7];
var myArray = [2, 4, 6];
function fillArray(ar1, ar2, i){
if (!i) i = 0;
if (!ar1[i]){
ar1[i] = ar2.shift();
}
if (++i < ar1.length && ar2.length > 0){
fillArray(ar1, ar2, i);
}
}
fillArray(otherArray, myArray); // this will update the content of originals arrays,
// use otherArray.slice() to get a copy.
document.getElementById("result").innerHTML = JSON.stringify(otherArray);
<div id="result"></div>
If you want to add elements (because there is other items in myArray and there is no space left in otherArray) you can change the condition to continue replacing the && with ||
if (++i < ar1.length || ar2.length > 0){

Categories

Resources