Trying to merge two unsorted arrays in Javascript - 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.

Related

Flatten an array [duplicate]

This question already has answers here:
Flatten array of multiple nested arrays without recursion - javascript
(9 answers)
Closed last year.
I want to flatten an array with javascript but without recurssion and without prebuilt function.
This is the code but it dose not flatten the whole array and i want to know what is wrong with my code
input : [1, [2], [3,8, [[4]],9],[5,6]]
output : [1, 2, 3, 8, 5, 6]
Code :
flat = function(array) {
const output = []
for (let i = 0; i < array.length; i++) {
if (typeof array[i] == 'number') {
output.push(array[i])
} else {
let arr = array[i]
let n = 0
while (n < arr.length) {
if (typeof arr[n] == 'number') {
output.push(arr[n])
n++
} else {
arr = arr[n]
n--
console.log(arr, n);
}
}
}
}
return output
}
It's possible to do, but it involves managing a stack yourself, manually:
const input = [1, [2], [3, 8, [[4]], 9], [5, 6]];
const result = [];
const stack = [{current: input, pos: 0}];
while (stack.length > 0) {
let {current, pos} = stack.pop();
if (pos < current.length) {
let item = current[pos++];
stack.push({current, pos});
if (Array.isArray(item)) {
stack.push({current: item, pos: 0});
} else {
result.push(item);
}
}
}
console.log(result);
This is what a recursive approach would do in the background, more or less. If your concern about recursion was that you don't like/understand it, not sure that you will find this one more likeable.

issue with merge sorted arrays problem using 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}));

JavaScript: Add sum of even value elements to each odd value element in an given array; show the new array

I need to write a code that adds the sum of even value elements to each odd value element in a given array and then show the new array.
Example:
array = [2,3,4,5,6,7,8,9]
Requested sum is 20. The new generated array should look like:
array = [2, 23, 4, 25, 27, 8, 29]
What I have done so far:
let oldArray = [2, 3, 4, 5, 6, 7, 8, 9];
const sumArray = arr => arr.filter(i => !(i % 2)).reduce((a, b) => a + b);
let newArray = oldArray.map (i => i%2 == 1 + sumArray);
console.log(newArray);
Take a look at this:
let array = [2, 3, 4, 5, 6, 7, 8, 9];
console.log(array.map(x=>x%2==0?x:x+array.reduce((a,b)=> a + b*((b+1)%2) )))
It's logging an array built on the original array: if the element is even, you leave it that way. If not, you add the sum of the even numbers. How do you do this? You add the element multiplied by the rest of the division of this element added to 1 by 2.
let array = [2,3,4,5,6,7,8,9];
let newarray = [];
let sum = 0;
for(let i=0; i<array.length; i++) {
if(array[i]%2 === 0) {
sum += array[i];
}
}
for(let i=0; i<array.length; i++) {
if(array[i]%2 === 0) {
newarray.push(array[i]);
}
else {
newarray.push(array[i]+sum);
}
}

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]

Merging of two arrays, store unique elements, and sorting in jQuery

var Arr1 = [1,3,4,5,6];
var Arr2 = [4,5,6,8,9,10];
I am trying to do merge these two arrays and output coming is [1,3,4,5,6,4,5,6]
I have used $.merge(Arr1, Arr2); this piece to merge them. Using alert I can see the merged array like above.
Now my question is how can I get the following output:
[1,3,4,5,6,8,9,10]
i.e. the elements should be unique as well as sorted in the same manner I have mentioned.
Please help.
You can use Array.prototype.sort() to do a real numeric sort and use Array.prototype.filter() to only return the unique elements.
You can wrap it into a helper similar to this:
var concatArraysUniqueWithSort = function (thisArray, otherArray) {
var newArray = thisArray.concat(otherArray).sort(function (a, b) {
return a > b ? 1 : a < b ? -1 : 0;
});
return newArray.filter(function (item, index) {
return newArray.indexOf(item) === index;
});
};
Note that the custom sort function works with numeric elements only, so if you want to use it for strings or mix strings with numbers you have to update it off course to take those scenarios into account, though the rest should not change much.
Use it like this:
var arr1 = [1, 3, 4, 5, 6];
var arr2 = [4, 5, 6, 8, 9, 10];
var arrAll = concatArraysUniqueWithSort(arr1, arr2);
arrAll will now be [1, 3, 4, 5, 6, 8, 9, 10]
DEMO - concatenate 2 arrays, sort and remove duplicates
There is many ways of doing this I'm sure. This was just the most concise I could think off.
merge two or more arrays + remove duplicities + sort()
jQuery.unique([].concat.apply([],[[1,2,3,4],[1,2,3,4,5,6],[3,4,5,6,7,8]])).sort();
One line solution using just javascript.
var Arr1 = [1,3,4,5,6];
var Arr2 = [4,5,6,8,9,10];
const sortedUnion = [... new Set([...Arr1,... Arr2].sort((a,b)=> a-b))]
console.log(sortedUnion)
This looks like a job for Array.prototype.indexOf
var arr3 = arr1.slice(), // clone arr1 so no side-effects
i; // var i so it 's not global
for (i = 0; i < arr2.length; ++i) // loop over arr2
if (arr1.indexOf(arr2[i]) === -1) // see if item from arr2 is in arr1 or not
arr3.push(arr2[i]); // it's not, add it to arr3
arr3.sort(function (a, b) {return a - b;});
arr3; // [1, 3, 4, 5, 6, 8, 9, 10]
a = [1, 2, 3]
b = [2, 3, 4]
$.unique($.merge(a, b)).sort(function(a,b){return a-b}); -> [1, 2, 3, 4]
Update:
This is a bad idea, since the 'unique' function is not meant for use on numbers or strings.
However, if you must then the sort function needs to be told to use a new comparator since by default it sorts lexicographically.
Using underscore.js:
_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]).sort(function(a,b){return a-b});
=> [1, 2, 3, 10, 101]
This example is taken directly from underscore.js, a popular JS library which complements jQuery
I did that as follows, where t1 and t2 are my two tables.
The first command put the values of the table t2 to the t1. The second command removes the duplicate values from the table.
$.merge(t1, t2);
$.unique(t1);
function sortUnique(matrix) {
if(matrix.length < 1 || matrix[0].length < 1) return [];
const result = [];
let temp, ele;
while(matrix.length > 0) {
temp = 0;
for(let j=0; j<matrix.length; j++) {
if(matrix[j][0] < matrix[temp][0]) temp = j;
}
if(result.length === 0 || matrix[temp][0] > result[result.length-1]) {
result.push(matrix[temp].splice(0,1)[0]);
} else {
matrix[temp].splice(0,1);
}
if(matrix[temp].length===0) matrix.splice(temp, 1);
}
return result;
}
console.log(sortUnique([[1,4,8], [2,4,9], [1,2,7]]))
Using JavaScript ES6 makes it easier and cleaner. Try this:
return [...Arr1, ...Arr2].filter((v,i,s) => s.indexOf(v) === i).sort((a,b)=> a - b);
and there you have it. You could build it in a function like:
function mergeUniqueSort(Arr1, Arr2){
return [...Arr1, ...Arr2].filter((v,i,s) => s.indexOf(v) === i).sort((a,b)=> a - b);
}
and that settles it. You can also break it down using ES6. Use a Spread Operator to combine arrays:
let combinedArrays = [...Arr1, ...Arr2]
then get the unique elements using the filter function:
let uniqueValues = combinedArrays.filter((value, index, self ) => self.indexOf(value) === index)
Lastly you now sort the uniqueValue object:
let sortAscending = uniqueValues.sort((a-b) => a - b) // 1, 2, 3, ....10
let sortDescending = uniqueValues.sort((b-a) => b - a) // 10, 9, 8, ....1
So you could use any part, just in case.

Categories

Resources