1

I am merging two sorted arrays in JavaScript. When I call function with two arrays having numbers it works fine, but when I call that function with strings then it does not work. Why?

function mergeSortedArrays(array1, array2) {
  const mergedArray = [];
  let array1Item = array1[0];
  let array2Item = array2[0];
  let i = 1;
  let j = 1;

  if (array1.length === 0) {
    return array2;
  }
  if (array2.length === 0) {
    return array1;
  }

  while (array1Item || array2Item) {
    if (array2Item === undefined || array1Item < array2Item) {
      mergedArray.push(array1Item);
      array1Item = array1[i];
      i++;
    } else {
      mergedArray.push(array2Item);
      array2Item = array2[j];
      j++;
    }
  }
  console.log(mergedArray);
}

//working?
mergeSortedArrays([0, 3, 4, 12, 222], [3, 4, 6, 30]);

// not working why?
mergeSortedArrays(["0", "3", "4", "12", "222"], ["3", "4", "6", "30"]);
isherwood
  • 58,414
  • 16
  • 114
  • 157
Rahul Syal
  • 545
  • 2
  • 6
  • 21
  • 4
    Strings are compared lexically; `"222"` is smaller than `"3"`. –  Aug 30 '19 at 16:48
  • As @ChrisG said strings could not be compared like the numbers. – SMAKSS Aug 30 '19 at 16:51
  • 1
    is it really necessary to downvote OP's question? For me, it seems ok, he have a real question, with real code, he only didn't know about the lexical comparassion – Calvin Nunes Aug 30 '19 at 17:00
  • @CalvinNunes It's fine, because a minimum amount of research would've been enough –  Aug 31 '19 at 01:20

2 Answers2

2

As said in the comments, strings in JS are compared lexically , so, "222" is smaller than "3".

A solution that I see that you can use, is this one:
After checking the arrays for nullity, then concat then into mergedArray, then use the JS function sort(), with the basic return of value1 - value2, that way it will sort the strings in the order you want, and also will work for numbers.

(Further read: Why is one string greater than the other when comparing strings in JavaScript?)

function mergeSortedArrays(array1, array2) {
  let mergedArray = [];

  if (array1.length === 0) {
    return array2;
  }
  if (array2.length === 0) {
    return array1;
  }

  mergedArray = array1.concat(array2)
  mergedArray.sort(function(a, b) {
    return a - b
  })
  console.log(mergedArray);
  return mergedArray;
}


mergeSortedArrays([0, 3, 4, 12, 222], [3, 4, 6, 30]);
mergeSortedArrays(["0", "3", "4", "12", "222"], ["3", "4", "6", "30"]);

BUT, be knowing that this solution will only work as expected if the strings are representations of numbers ("1", "2",...), if it is something like "aa", "abc", "b" it probably won't work well and another solution may be needed. (something like this: https://stackoverflow.com/a/51169/8732818)

Calvin Nunes
  • 6,376
  • 4
  • 20
  • 48
0

Sort for string works differently than numbers. Its based on the ASCII table values. For example "99" > "100000" return should return true