Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 12 of 12
  1. #1
    New Coder
    Join Date
    Oct 2011
    Posts
    37
    Thanks
    13
    Thanked 1 Time in 1 Post

    Javascript sort not working for my multidimensional array

    I have the following array called 'datacontent' that have the following data:
    (4, RX33, )
    (3, RX54, )
    (102, RX44, )
    (1, R100, Retail Branch 100)
    (2, RX12, )
    (100, RX55, )

    I want them to be sorted into this order:
    (1, R100, Retail Branch 100)
    (2, RX12, )
    (3, RX54, )
    (4, RX33, )
    (100, RX55, )
    (102, RX44, )

    But it is always not sorted and it will give me as follows:
    (2, RX12, )
    (3, RX54, )
    (4, RX33, )
    (100, RX55, )
    (102, RX44, )
    (1, R100, Retail Branch 100)

    My code is as follows:
    Code:
    function sortby(i) {
    	return function(a,b){a = a[i];b = b[i];return a.toLowerCase() == b.toLowerCase() ? 0 : (a.toLowerCase() < b.toLowerCase() ? -1 : 1)}
    }
    datacontent.sort(sortby(1));
    Appreciate any help.

  • #2
    Regular Coder
    Join Date
    Sep 2010
    Location
    Far far away
    Posts
    122
    Thanks
    0
    Thanked 16 Times in 16 Posts
    Function sortby should accept two arguments meaning two items of sorted array.This function is sorting criterion and should be passed as an argument to the Array#sort method. Look below
    Code:
    function sortby(a, b)
    {
    // define here how you want to sort items
    };
    
    datacontent.sort(sortby);

  • #3
    Gütkodierer
    Join Date
    Apr 2009
    Posts
    2,127
    Thanks
    1
    Thanked 426 Times in 424 Posts
    First of all, disregard that previous reply — your general setup is ok.

    Second, you're using it wrong: sortby returns a compare function that compares the arrays by their entries with index i. You want to compare them by index 0 (the first array element), so it has to be sortby(0), and not sortby(1). That said, I don't believe the result you posted. It's supposed to be ordered alphanumerically by those "RX" strings, but the result you posted isn't.

    Third, alphanumerical ordering won't do you any good for those numbers, because 100 will come before 2. You will want to check whether the index you are comparing holds a number or a string, and then do the appropriate type of comparison:

    PHP Code:
    var datacontent = [
        [
    4'RX33'],
        [
    3'RX54'],
        [
    102'RX44'],
        [
    1'R100'],
        [
    2'RX12'],
        [
    100'RX55']
    ];

    function 
    sortby(i) {
        return function (
    ab) {
            
    a[i];
            
    b[i];
            if (
    typeof a == 'number') {
                return 
    b;
            }
            else {
                return 
    == : (? -1);
            }
        };
    }

    datacontent.sort(sortby(0));
    console.log(datacontent); 
    As you can see, this is assuming that the first entry of those arrays is really a number, and not a string containing a number, which isn't clear from what you have posted. If those are strings containing numbers, you have to replace that typeof check with a regexp.
    .My new Javascript tutorial site: http://reallifejs.com/
    .Latest article: Calculators — Tiny jQuery calculator, Full-fledged OOP calculator, Big number calculator
    .Latest quick-bit: Including jQuery — Environment-aware minification and CDNs with local fallback

  • Users who have thanked venegal for this post:

    saltoceana (10-12-2011)

  • #4
    Regular Coder
    Join Date
    Sep 2010
    Location
    Far far away
    Posts
    122
    Thanks
    0
    Thanked 16 Times in 16 Posts
    Hi venegal,

    Could you be so kind as to point, please, which part of my post brought you to the decision to disregard my reply? Let's learn these links from MSDN and MDN, respectively:

    http://msdn.microsoft.com/en-us/libr...=VS.90%29.aspx
    https://developer.mozilla.org/en/Jav...cts/Array/sort

    Accordingly these docs my description is correct although it might be not considered to complete. Taking in account the function used by the topic starter is a closure, returning another function it is correct too, but he should pass 0 to refer to the first item of an inner array.

    But I'd like to point your attention that your function is not good because it checks a type of arguments each time when it is called. Think, each time when the function is called! This is not good practice. More over this is not good to offer such kind of code to others.

  • #5
    Gütkodierer
    Join Date
    Apr 2009
    Posts
    2,127
    Thanks
    1
    Thanked 426 Times in 424 Posts
    siberia-man: My advice to disregard your reply only meant that it doesn't help solve the actual problem. There's no doubt that as an advice how to generally use a compare function with Array.sort it's correct, but for the actual issue, it's confusing: the way the sortby function is set up in the OP, it definitely should not accept two parameters, and the actual issues are not addressed.

    As for the type checking within the compare function: I'm just working with the code the OP posted here. It's obviously set up to allow for ordering by arbitrary array index, and there's no way to do that except by checking the type in the compare function. The check could be done on the outside, but as soon as it's done there, the whole closure setup allowing the outside code to be agnostic of what's inside those arrays would be useless. Since the OP's code is well written overall, I just assumed it's by design that the outside code shouldn't have to care about what's inside the arrays.
    .My new Javascript tutorial site: http://reallifejs.com/
    .Latest article: Calculators — Tiny jQuery calculator, Full-fledged OOP calculator, Big number calculator
    .Latest quick-bit: Including jQuery — Environment-aware minification and CDNs with local fallback

  • #6
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,537
    Thanks
    77
    Thanked 4,381 Times in 4,346 Posts
    This is confusing:
    Code:
    return function (a, b) {
        a = a[i];
        b = b[i];
    Cute, but confusing.

    Just to clarify it, I would have written:
    Code:
    return function (arrA, arrB) {
        var a = arrA[i];
        var b = arrB[i];
    But...

    But I don't think the answer is complete, at all.

    Or, rather, it *MIGHT* not be, depending on the data given.

    Suppose this was the data, instead:
    Code:
    var datacontent = [
        [4, 'RX33'],
        [3, 'RX54'],
        [102, 'RX44'],
        [1, 'R100'],
        [2, 'RX12'],
        [100, 'RX55'],
        [3, 'RX22'],
        [3, 'RX95']
    ];
    The three elements with first subelement = 3 won't come out in second subelement order, which is what I would assume we should expect.

    So I'd just write it dirt simple:
    Code:
    function sortDatacontent( arrA, arrB )
    {
        var chk = arrA[0] - arrB[0];
        if ( chk != 0 ) return chk;
        return arrA[1] == arrB[1] ? 0 : (arrA[1] < arrB[1] ? -1 : 1); 
    }
    datacontent.sort( sortDatacontent );
    Not as general/flexible, but will do the job an in very little code.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • Users who have thanked Old Pedant for this post:

    saltoceana (10-12-2011)

  • #7
    Gütkodierer
    Join Date
    Apr 2009
    Posts
    2,127
    Thanks
    1
    Thanked 426 Times in 424 Posts
    Quote Originally Posted by Old Pedant View Post
    But I don't think the answer is complete, at all.

    Or, rather, it *MIGHT* not be, depending on the data given.
    I sort of assumed that the integer is a unique ID, but you're right, we don't know that.
    .My new Javascript tutorial site: http://reallifejs.com/
    .Latest article: Calculators — Tiny jQuery calculator, Full-fledged OOP calculator, Big number calculator
    .Latest quick-bit: Including jQuery — Environment-aware minification and CDNs with local fallback

  • #8
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,537
    Thanks
    77
    Thanked 4,381 Times in 4,346 Posts
    Yep, it's one of the joys of forum postings. You never know if you've got the whole story or not. <grin/>

    So here's a fun challenge for you: Write a sort function that works for non-homogeneous multi-dimensional arrays of any number of dimensions. Be sure to handle the case where two values being compared are, say, date and string. Or number and boolean. Or...
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #9
    Gütkodierer
    Join Date
    Apr 2009
    Posts
    2,127
    Thanks
    1
    Thanked 426 Times in 424 Posts
    Quote Originally Posted by Old Pedant View Post
    So here's a fun challenge for you: Write a sort function that works for non-homogeneous multi-dimensional arrays of any number of dimensions. Be sure to handle the case where two values being compared are, say, date and string. Or number and boolean. Or...
    Interesting. The function comparing the two arrays, I'd probably write like this:

    PHP Code:
    // Compare function for sorting multi-dimensional arrays
    function multiDimCompare(ab) {
        
    // Remember current array index
        
    var 0;
        return (function 
    recursiveCompare() {
            
    // If one of the two arrays doesn't have any more entries before a conclusion 
            // has been reached, array length will be used for sorting
            
    if (>= Math.max(a.lengthb.length)) return a.length b.length;
            
    // Compare the actual entries
            
    var difference compare(a[i], b[i++]);
            
    // If equal, try again with next array index, else return difference
            
    return difference == recursiveCompare() : difference;
        }());
    }; 
    As for the actual compare function, you'd have to know the business logic in order to decide how to compare, say, a Date and a String. I realize that this challenge has been more of a joke, though, so I'll leave the implementation details to you.
    .My new Javascript tutorial site: http://reallifejs.com/
    .Latest article: Calculators — Tiny jQuery calculator, Full-fledged OOP calculator, Big number calculator
    .Latest quick-bit: Including jQuery — Environment-aware minification and CDNs with local fallback

  • #10
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,537
    Thanks
    77
    Thanked 4,381 Times in 4,346 Posts
    I only tossed in Date because it's built into the JS language. I'd probably just compare the two getTime() values [assuming both are dates]. The heterogenous part is what would make a general solution tough, if not impossible.

    I was actually serious about the idea. I was thinking of maybe creating a prototype where the user could specify all the rules for comparisons (or opt to take the defaults, of course).
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #11
    New Coder
    Join Date
    Oct 2011
    Posts
    37
    Thanks
    13
    Thanked 1 Time in 1 Post
    Thank you everyone for such helpful response.

    Hi Old Pedant,
    Just to point out one thing, the entry [1, 'R100'] should be [1, R100, Retail Branch 100] as it is the only array that contain 3 elements.

    I support your sentence ...

    Quote Originally Posted by Old Pedant View Post
    So here's a fun challenge for you: Write a sort function that works for non-homogeneous multi-dimensional arrays of any number of dimensions. Be sure to handle the case where two values being compared are, say, date and string. Or number and boolean. Or...
    ... as it do help to tackle all kinds of sorting of two values.


    Hi Venegal,
    I used your first code and modify it as shown ...

    Code:
    function sortby(i) {
        return function (a, b) {
            a = parseInt(a[i]);
            b = parseInt(b[i]);
            if (typeof a == 'number') {
                return a - b;
            }
            else {
                return a == b ? 0 : (a < b ? -1 : 1);
            }
        };
    }
    	
    datacontent.sort(sortby(0));
    console.log(datacontent);
    ... and now it is working awesome.

  • #12
    Gütkodierer
    Join Date
    Apr 2009
    Posts
    2,127
    Thanks
    1
    Thanked 426 Times in 424 Posts
    Quote Originally Posted by Old Pedant View Post
    I only tossed in Date because it's built into the JS language. I'd probably just compare the two getTime() values [assuming both are dates]. The heterogenous part is what would make a general solution tough, if not impossible.

    I was actually serious about the idea. I was thinking of maybe creating a prototype where the user could specify all the rules for comparisons (or opt to take the defaults, of course).
    I'm not sure comparing different types makes a whole lot of sense for sorting (except maybe numbers and number-strings). If the types are different, they should probably just be sorted by type. Also, passing those comparison rules to that prototype function sounds exactly like passing a custom compare function to Array.sort to me, so I don't really see the advantage.

    Btw, comparing two Dates is no problem at all using standard comparison operators, so there's no need for getTime(), or, for that matter, any custom compare function.
    .My new Javascript tutorial site: http://reallifejs.com/
    .Latest article: Calculators — Tiny jQuery calculator, Full-fledged OOP calculator, Big number calculator
    .Latest quick-bit: Including jQuery — Environment-aware minification and CDNs with local fallback


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •