简体   繁体   中英

javascript sorting 2D array makes duplicates in my array

I am trying to sort my 2D array according to column 3. when I sort it with sort function, all the array members become duplicates of one member of the original array.

so for example;

my original array:

[12, AAA, eee, 5]
[58, BBB, zzz, 3]
[28, CCC, ddd, 6]
[18, DDD, fff, 9]

I want it to become :

[18, DDD, fff, 9]
[28, CCC, ddd, 6]
[12, AAA, eee, 5]
[58, BBB, zzz, 3]

I use the code :

function sortByColumn(a, colIndex){

    a.sort(sortFunctionq);

    function sortFunctionq(a, b) {
        if (a[colIndex] === b[colIndex]) {
            return 0;
        }
        else {
            return (a[colIndex] > b[colIndex]) ? -1 : 1;
        }
    }

    return a;
}

var sorted_a = new Array(15);
sorted_a = sortByColumn(arr, 3);

now the array becomes:

[18, DDD, fff, 9]
[18, DDD, fff, 9]
[18, DDD, fff, 9]
[18, DDD, fff, 9]

I am using javascript on Samsung Gear watch. maybe it does not support the "sort" function correctly. is there a way to sort 2D array without using sort function ?


final code is:

    var sorted_a = new Array(15);
    sorted_a = sortByColumn(arrx, 3);
    arrx= sorted_a;

function bubbleSort(a, fCompare) {
    if( a.length < 2)   {return a;}
    for( var length = a.length-1; length; --length) {
        var noSwaps = true;
        var temp;
        for(var c=0; c<length; ++c) {
            if( fCompare( a[c], a[c+1]) > 0) {
                temp = a[c+1];
                a[c+1] = a[c];
                a[c] = temp;
                noSwaps = false;
            }
        }
        if( noSwaps) {break;}
    }
}

function sortByColumn(a, colIndex){
    function sortFunctionq(a, b) {
        if (a[colIndex] === b[colIndex]) {
            return 0;
        }
        else {
            return (a[colIndex] > b[colIndex]) ? -1 : 1;
        }
    }
    //return bubbleSort(a, sortFunctionq);
    return bubbleSort(a.slice(), sortFunctionq);
}

but now nothing is available in the array.

for those who ask: if I remove the sort function and use arrx as it is, I can reach 2D array elements with arrx[1][1] but with the code above arrx[1][1] returns null.


I changed it a bit and now it seems to work. But now I need to remove duplicates as well. How can I do that ?

current code:

    var arrx = new Array(50);
    for (var j = 0; j<50; j++){
        arrx[j] = arr[j].split("|+");
    }
    var arry = new Array(50);
    arry = bubbleSort(arrx);

function bubbleSort(a) {
    for( var r = 49; r >= 0; --r) {
        var noSwaps = true;
        var temp = new Array(50);
        for(var c=0; c<r; ++c) {
            if (a[c][3] < a[c+1][3]) {
                temp = a[c+1];
                a[c+1] = a[c];
                a[c] = temp;
                noSwaps = false;
            }
        }
        if( noSwaps) {break;}
    }
    return a;
}

The direct answer to you question is "yes, it is possible to sort an array without using the array's sort method". A simple example using bubble sort:

 function bubbleSort(a, fCompare) { if( a.length < 2) return a; for( var length = a.length-1; length; --length) { var noSwaps = true; var temp; for( i=0; i<length; ++i) { if( fCompare( a[i], a[i+1]) > 0) { temp = a[i+1]; a[i+1] = a[i]; a[i] = temp; noSwaps = false; } } if( noSwaps) break; } } function sortByColumn(a, colIndex){ function sortFunctionq(a, b) { if (a[colIndex] === b[colIndex]) { return 0; } else { return (a[colIndex] > b[colIndex]) ? -1 : 1; } } return bubbleSort(a, sortFunctionq); } var a = [ [12, 'AAA', 'eee', 5], [58, 'BBB', 'zzz', 3], [28, 'CCC', 'ddd', 6], [18, 'DDD', 'fff', 9], ]; var sortedA = sortByColumn(a,2) // updates a in-place, as well console.log( JSON.stringify(sortedA)) 

However

Note that both the sort method of an array and the bubbleSort above change the order of elements in the array being sorted, without creating a shallow copy of the array. While bubbleSort may show the Samsung JS engine has a problem, more than likely it will not and produce the same result.

Because sorting sorts the array in place, you may wish to check if creating a shallow copy of it before sorting solves the problem. EG by replacing the return statement in the example with

return a.slice().sort(functionq) // OR
return bubbleSort(a.slice(), functionq)


Debugging notes:

  1. JavaScript arrays are objects. The value of an object variable is a reference of some kind used by the JavaScript engine to access object properties. The reference could be a memory pointer or some other value used by the engine to access object data. When you assign an object to a variable, its existing content is overwritten. If you assign the same object value to two variables, they hold the same refernce value and refer to the same set of object data.

     var arry = new Array(50); arry = bubbleSort(arrx); 

    unnecessarily creates a new Array, because the new Array value is overwritten in the second line. It can be simplified as

     var arry = bubbleSort( arrx). 

    Note that JavaScript arrays can grow and shrink and do not have some pre-allocated length.

  2. Both the bubble sort code and the inbuilt array sort method (inherited by an array instance from the Array.prototype object, and documented on MDN under Array.prototype.sort ) sort the array in place and return an object reference to the array being sorted. After

     arry = bubbleSort(arrx); // OR arry = arrx.sort(sortFunction) 

    the value of arry is the same as arrx . If you want to make a copy of the array that is immune to arrx modificatioms of first dimension values, make a shallow copy of the input array before sorting:

     arry = bubbleSort(arrx.slice()); 

    If you want to make a copy that is immune to modifications to either dimension value then make a shallow copy of both dimensions' arrays as for example:

     arry = bubbleSort( arrx.map(element => element.slice()) 

    This creates new arrays from both dimensions of arrx before sorting.

If you are still getting duplicate entries after this you will need to find out where in the code the duplicates are being assigned.


Tip

Check there are no typos in conditional tests that use = (the assignment operator) instead of == or === operators to test for equality. This is a good way of inadvertently assigning values to something that was not meant to be changed.

All you need to change is to return the sorted array.

 const data = [ [12, 'AAA', 'eee', 5], [58, 'BBB', 'zzz', 3], [28, 'CCC', 'ddd', 6], [18, 'DDD', 'fff', 9] ]; function sortByColumn(a, colIndex){ function sortFunctionq(a, b) { if (a[colIndex] === b[colIndex]) { return 0; } else { return (a[colIndex] > b[colIndex]) ? -1 : 1; } } return a.sort(sortFunctionq); //^^^^^^^^^^^^^^^^^^^^^^^^^^^ } const result = sortByColumn(data, 3); console.log(result); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM