javascript odd and even separation in an array of numbers

前端 未结 5 1618
一整个雨季
一整个雨季 2021-01-06 19:04

i wants to separate an array with two groups (odd and even) sequentially. but when i try this:

相关标签:
5条回答
  • 2021-01-06 19:27

    why 4,8,6,2 instead of 2,4,6,8?

    it is because you are modifying the same Array which you are looping through. to understand better, lets loop through your code

    after
    1st Loop: array: [1, 2, 3, 4, 5, 6, 7, 8, 9];
    2nd loop: array: [1, 3, 4, 5, 6, 7, 8, 9, 2];
    3rd loop: array: [1, 3, 5, 6, 7, 8, 9, 2, 4];
    4th loop: array: [1, 3, 5, 7, 8, 9, 2, 4, 6];
    5th loop: array: [1, 3, 5, 7, 9, 2, 4, 6, 8];
    6th loop: array: [1, 3, 5, 7, 9, 4, 6, 8, 2];
    7th loop: array: [1, 3, 5, 7, 9, 4, 8, 2, 6];
    8th loop: array: [1, 3, 5, 7, 9, 4, 8, 6, 2];
    9th loop: array: [1, 3, 5, 7, 9, 4, 8, 6, 2];
    

    to separate out odd/even in an array, we will have to filter out odd and even separately and push evenArray in the end of oddArray(filtered Array)

    var input = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    
    input = input.sort((a, b)=> a-b); //to sort array if not sorted already
    var evenArr = [];
    input = input.filter(item => {
      if (item % 2 != 0)
        return true
      else {
        evenArr.push(item);
        return false;
      }
    })
    
    Array.prototype.push.apply(input, evenArr);
    
    console.log(input);

    0 讨论(0)
  • 2021-01-06 19:34

    Because you move every found even value to the end of the array:

    0: 1 2 3 4 5 6 7 8 9
         ^-------------v
    1: 1 3 4 5 6 7 8 9 2   3 is not checked, because of the incremented index after splicing
           ^-----------v
    2: 1 3 5 6 7 8 9 2 4   5 is not checked
             ^---------v
    3: 1 3 5 7 8 9 2 4 6   7 is not checked
               ^-------v
    4: 1 3 5 7 9 2 4 6 8   9 is not checked
                 ^-----v
    5: 1 3 5 7 9 4 6 8 2
                   ^---v
    6: 1 3 5 7 9 4 8 2 6
                     ^-v
    7: 1 3 5 7 9 4 8 6 2
                       |
    8: 1 3 5 7 9 4 8 6 2
    

    But, you do not check the value after the found even value, like the value 3 in line zero, because it is never checked and stays at this place, as well as other actually uneven values. You could try the whole again with all even at the beginning of the array, like

    var array = [2, 4, 6, 8, 1, 3, 5, 7, 9];
        
    for (var i = 0; i < array.length; i++) {
        if (array[i] % 2 === 0) {
            array.push(array.splice(i, 1)[0]);
            console.log(i + ': ' + array.join(' '));
        }
    }
    
    console.log(array);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    Solution

    You could use a length for checking and reduce the length for every found even value. In this case, the index stays at the value, because at the index is now the next element for checking.

    var array = [1, 2, 3, 4, 5, 6, 7, 8, 9],
        i = 0,
        l = array.length;
    
    while (i < l) {
        if (array[i] % 2 === 0) {
            array.push(array.splice(i, 1)[0]);
            l--;
            continue;
        }
        i++;
    }
    
    console.log(array);

    Or just sort.

    By moving odd values to top and then sort by value.

    var array = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    
    array.sort((a, b) => b % 2 - a % 2 || a - b);
    console.log(array);

    0 讨论(0)
  • 2021-01-06 19:34

    The way you do it is so complicated. You can simply achieve that with array.prototype.filter and array.prototype.concat:

    var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    arr = arr.filter(e => e%2).concat(arr.filter(e => e%2 === 0));
    console.log(arr);

    0 讨论(0)
  • 2021-01-06 19:38

    why 4,8,6,2 instead of 2,4,6,8?

    Basically when half of the iterations are done, it is re-processing the pushed items.

    You need to change the for-loop as

    for (var i = 0; i < arr.length/2; i++) {
      if (arr[i]%2 == 0) {
        arr.push(arr.splice(i, 1)[0]);
      }
    }
    

    Demo

    var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    
    for (var i = 0; i < arr.length / 2; i++) {
      if (arr[i] % 2 == 0) {
        arr.push(arr.splice(i, 1)[0]);
      }
    }
    
    console.log(arr);

    Edit

    And if the order of items is not always sorted, then you apart from sorting it first, you can reduce the length variable.

    var arr = [1, 2, 4, 3, 5, 6, 7, 8, 9];
    var length = arr.length;
    for (var i = 0; i < length; i++) {
      console.log(i,arr[i]);
      if (arr[i] % 2 == 0) {
        arr.push(arr.splice(i, 1)[0]);
        console.log("result ", arr)
        length--;
        i--;
      }
    }
    console.log(arr)
    
    0 讨论(0)
  • 2021-01-06 19:47

    I believe this can be covered by lodash _.partition:

    var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    var [odds, evens] = _.partition(arr, function(n) {
      return n % 2;
    });
    console.log(_.concat(odds, evens));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

    Or even shorter:

    _.groupBy(arr, function(n) {return (n % 2) ? 'odd' : 'even';})
    
    0 讨论(0)
提交回复
热议问题