3

I came up with this in order to merge two sorted arrays and remove duplicates. I want to know if I can do better.

Any ideas?

var mergeArrays = function(arr1 , arr2){
var mergedArray = new Array();
var i = 0, j=0,k=0;
var prev = -1;
while(arr1.length  > i || arr2.length > j){
    if(arr1[i] == arr2[j]){
        mergedArray[k] = arr1[i];
        i++;
        j++;
    }else if(arr1[i] < arr2[j] || arr2[j] == undefined){
        mergedArray[k] = arr1[i];
        i++;
    }else{
        if(arr2[j]>prev) {
            mergedArray[k] = arr2[j];
        }
        j++;
    }

    prev = mergedArray[k];
    k++;

}

return mergedArray;
}
1
  • 3
    If this is woking code (it does what you want it to do, without errors) you could try posting it on codereview.stackexchange.com That site is for improving your code. Commented Jul 14, 2015 at 18:31

5 Answers 5

2

You can try this

var mergeArrays = function(arr1 , arr2){
    var mergedArray = arr1.concat(arr2);

    var uniqueArray = mergedArray.filter(function(elem, pos) {
        return mergedArray.indexOf(elem) == pos;
    });
    return uniqueArray;
} 
Sign up to request clarification or add additional context in comments.

Comments

1
function merge(...args) {
    return [...new Set(args.reduce((acc,val) => [...acc, ...val]))].sort();
} //Short and crisp solution to merge arrays, sort them and remove duplicates

Comments

0

If you're open to underscore.js, and it's great, then you could try something like _.union

http://underscorejs.org/#union

Comments

0

I would do it this way

function unique(array) {
    var a = array.concat();
    for(var i=0; i<a.length; ++i) {
        for(var j=i+1; j<a.length; ++j) {
            if(a[i] === a[j])
                a.splice(j--, 1);
        }
    }
    return a;
};
var array1 = ["...",",,,"];
var array2 = ["///", "..."];
var array3 = unique(array1.concat(array2));

Comments

0

First of all, your code does not do, what you think it does. Try to run it with this case:

array1 = [0,0,0,1,1,1,3,5,5,5,5,9];
array2 = [1,1,1,1,1,1];

and you'll see what's wrong.

For most usecases with primitive data, you can go very well with native functionality, it does exactly what you are trying to achieve:

let uniqueArr = [];

uniqueArr = [...new Set ([...array1, ...array2])].sort();

But this wasn't your question, I assume. If the data is complex or just for fun we can think of other solutions.

There are many ways to do things: some are more time-intensive, some need more space. These are my ideas for this solution, feel free to correct or credit.

function binarySearch(arr, left, right, x){
    // fastest search in a sorted (!) array
    
    if (right >= l) {
        let mid = left + Math.floor((right - l) / 2);
  
        if (arr[mid] == x)
            return mid;
  
        if (arr[mid] > x)
            return binarySearch(arr, left, mid - 1, x);

        return binarySearch(arr, mid + 1, right, x);
    }
  
    // element is not present in array
    return -1;
}

function cloneArrayKeepUniqueOnly(array, array2){
    // array must be sorted, arg remains unmodified
    // keeps only unique elements from the array
    let uniqueOnly = [];

    for (let i = 0; i < array.length; i++ ){
        
        if (array[i] == array[i+1] ){
            i ++;
            continue; 
        } else if (array[i] != array[i-1] && binarySearch(array2, 0, array2.length, array[i]) == -1){
            
            uniqueOnly.push(array[i]);          
        }
    }
    
    return uniqueOnly;
}

function cloneArrKeepOneOfEach(array){
    // array must be sorted, arg remains unmodified
    // keeps one of every element from the array
    let oneOfEach = [];
    
    for (let i = 0; i < array.length; i++ ){
        
        if (array[i] == array[i+1] ){

            continue; 
        } else{
            oneOfEach.push(array[i]);
        }
    }
    
    return oneOfEach;
}

// main ---------------

let array1 = [0,0,0,0,1,1,2,3,4,5,5,5,5,6,7];
let array2 = [1,1,1,1,1,1,1,1];

let mergedArray_oneOfEach = [];
let mergedArray_onlyUniques = [];

let complementArr_uniques, complementArr; 

// uniques only --------------- start
mergedArray_onlyUniques = cloneArrayKeepUniqueOnly(array1, array2);
complementArr_uniques = cloneArrayKeepUniqueOnly(array2, array1); 

for (element of complementArr_uniques){
    mergedArray_onlyUniques.push(element);
}

console.log("mergedArray_onlyUniques: ", mergedArray_onlyUniques);
// uniques only --------------- end

//one of each ----------------start

mergedArray_oneOfEach = cloneArrKeepOneOfEach(array1);
complementArr = cloneArrKeepOneOfEach(array2);

while (i < mergedArray_oneOfEach.length){

    let searchIndex = binarySearch(complementArr, 0, complementArr.length-1, mergedArray_oneOfEach[i]);

    if (searchIndex != -1) {

        complementArr.splice(searchIndex, 1);
    } 
    i ++;
}

for (element of complementArr){
    mergedArray_oneOfEach.push(element);
}

console.log("mergedArray_oneOfEach: ", mergedArray_oneOfEach);

//one of each ----------------end

Alternative, merge the two arrays first, than sort em, than use a "reducing/cloning" function, or use a hash table. It would depend on characteristics of data and ressources at your disposal;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.