0
var array1 = [4,2];
var array2 = [1,3];

var concatArray = array1.concat(array2);

// iteration 1
concatArray_min = Math.min.apply(Math,concatArray);
var result = [concatArray_min];
var index = concatArray.indexOf(concatArray_min);
delete concatArray[index];
console.log(concatArray);    // returns [4,2,3]
console.log(result);         // returns [1]

// iteration 2
concatArray_min = Math.min.apply(Math,concatArray);
console.log(concatArray_min);   // returns NaN
result.push(concatArray_min);
index = concatArray.indexOf(concatArray_min);
delete concatArray[index];
console.log(concatArray);    // returns [4,2,3]
console.log(result);         // returns [1,NaN]

I am trying to merge two arrays and then sort them. I first concatenate the arrays and then delete the minimum from the unsorted concatenated array and push the minimum into the resulting array. This works at first, but fails for the second iteration as concatArray_min shows to be NaN. Perhaps the problem is in using Math.min.apply.(Math,concatArray) to get the minimum value and using delete to delete the element? Is there an alternative to this approach without using .sort()?

photon
  • 606
  • 4
  • 14
  • 31
  • 1
    Calling delete on concatArray is only setting that element to undefined. Instead use `concatArray.splice(index, 1)`. [http://jsfiddle.net/LXgtY/](http://jsfiddle.net/LXgtY/) – mathewbergt Jun 13 '14 at 23:02
  • 1
    @mathewbergt—it deletes the member, it doesn't set it to *undefined*, e.g. `a=[0,1,2]; delete a[1]; a.hasOwnProperty(1); // false`. Attempting to access an undefined member returns false: `a[1] // undefined`. – RobG Jun 13 '14 at 23:05
  • @RobG You are correct, it doesn't simply set the value to undefined, but it doesn't alter the indices of the other elements. The effective result is `[4, 2, undefined, 3]`, as `concatArray[2]` will return `undefined`. – user229044 Jun 13 '14 at 23:08
  • @RobG Yes this is correct. Sorry for the poor explanation. – mathewbergt Jun 13 '14 at 23:13
  • `var fixedArray = [4, 2, undefined, 3].filter(function(v){ return v!=undefined});` to fix arrays after calling delete on an index, the result will be [4,2,3] – joopmicroop Jun 14 '14 at 01:24

2 Answers2

4

By using delete you are removing an element from your array, without updating the length of the array, this leaves a gap in your Array that evaluates to undefined when you try to access it. Essentially you trying to apply min to [ 4, 2, undefined , 3 ].

You should remove your target element using Array.splice instead:

var array1 = [4,2];
var array2 = [1,3];

var concatArray = array1.concat(array2);

// iteration 1
concatArray_min = Math.min.apply(Math,concatArray);
var result = [concatArray_min];
var index = concatArray.indexOf(concatArray_min);
concatArray.splice(index,1);
console.log(concatArray);    // returns [4,2,3]
console.log(result);         // returns [1]
//
// // iteration 2
concatArray_min = Math.min.apply(Math,concatArray);
console.log(concatArray_min);   // returns NaN
result.push(concatArray_min);
index = concatArray.indexOf(concatArray_min);
concatArray.splice(index,1);
console.log(concatArray);    // returns [4,2,3]
console.log(result);         // returns [1,2]
Nick Tomlin
  • 28,402
  • 11
  • 61
  • 90
  • @RobG An excellent point, thanks for noting. I think I have been mislead by [this](http://stackoverflow.com/a/500617/1048479) SO answer. I have updated my own answer in an attempt to better describe what is going on. Feedback appreciated : ) – Nick Tomlin Jun 13 '14 at 23:13
1

You ask:

I am trying to merge two arrays and then sort them. Is there an alternative to this approach without using .sort()?

First of all I'd build it in a function for reusability.

Secondly let your code decide when it's done iterating.

=> jsfiddle

var array1 = [4,2], array2 = [1,3];
console.log( 'Result:', mergeSortUp(array1,array2) );

function mergeSortUp(a1, a2){
    var mergeRes = a1.concat(a2), sortRes = mergeRes, completed = false;
    while(!completed){
        var didTakeAction = false;
        for(var i in mergeRes)
            if(sortRes[i-1] && mergeRes[i] < sortRes[i-1]){
                var temp = sortRes[i-1]; sortRes[i-1] = mergeRes[i];sortRes[i]= temp;
                didTakeAction = true;
            }
        if(!didTakeAction) completed = true;
    }
    return sortRes;
}
joopmicroop
  • 891
  • 5
  • 15