0

I want to sort a json multilevel!! First sort by Sharia -> then by Volume[0] -> then by marketcap[0]

Non Sorted:

[
    {
        "Name": "Hcl",
        "sharia": true,
        "Volume": [
            25000,
            "moderate"
        ],
        "marketcap": [
            5000,
            "large"
        ]
    },
    {
        "Name": "rado",
        "sharia": false,
        "Volume": [
            50000,
            "high"
        ],
        "marketcap": [
            5000,
            "small"
        ]
    },
    {
        "Name": "ssinc ",
        "sharia": false,
        "Volume": [
            200,
            "low"
        ],
        "marketcap": [
            5000,
            "large"
        ]
    },
    {
        "Name": "sureshot",
        "sharia": false,
        "Volume": [
            20000,
            "moderate"
        ],
        "marketcap": [
            5000,
            "small"
        ]
    },
    {
        "Name": "Infosys",
        "sharia": true,
        "Volume": [
            50000,
            "high"
        ],
        "marketcap": [
            6000,
            "large"
        ]
    },
    {
        "Name": "orchid",
        "sharia": true,
        "Volume": [
            200,
            "low"
        ],
        "marketcap": [
            6000,
            "Large"
        ]
    },
    {
        "Name": "hero honda",
        "sharia": true,
        "Volume": [
            150,
            "low"
        ],
        "marketcap": [
            400,
            "medium "
        ]
    },
    {
        "Name": "bioffoz",
        "sharia": false,
        "Volume": [
            40000,
            "moderate"
        ],
        "marketcap": [
            5000,
            "large"
        ]
    }
]

As of now i am sorting once using the below function:

var sort_by = function(field, reverse, primer){

   var key = function (x) {return primer ? primer(x[field]) : x[field]};

   return function (a,b) {
       var A = key(a), B = key(b);
      return (A < B ? -1 : (A > B ? 1 : 0)) * [1,-1][+!!reverse];                
   }
}

For sorting A - Z

   company.sort(sort_by('Name', false, function(a){return a.toUpperCase()}));

For sorting Boolean:

company.sort(sort_by('sharia', true, function(a){return Boolean(a)}));

For sorting High to low:

company.sort(sort_by('sharia', true, parseint));

Sort By sharia(will look like this):

[
    {
        "Name": "Hcl",
        "sharia": true,
        "Volume": [
            25000,
            "moderate"
        ],
        "marketcap": [
            5000,
            "large"
        ]
    },
    {
        "Name": "orchid",
        "sharia": true,
        "Volume": [
            200,
            "low"
        ],
        "marketcap": [
            6000,
            "Large"
        ]
    },
    {
        "Name": "hero honda",
        "sharia": true,
        "Volume": [
            150,
            "low"
        ],
        "marketcap": [
            400,
            "medium "
        ]
    },
    {
        "Name": "Infosys",
        "sharia": true,
        "Volume": [
            50000,
            "high"
        ],
        "marketcap": [
            6000,
            "large"
        ]
    },
    {
        "Name": "ssinc ",
        "sharia": false,
        "Volume": [
            200,
            "low"
        ],
        "marketcap": [
            5000,
            "large"
        ]
    },
    {
        "Name": "sureshot",
        "sharia": false,
        "Volume": [
            20000,
            "moderate"
        ],
        "marketcap": [
            5000,
            "small"
        ]
    },
    {
        "Name": "rado",
        "sharia": false,
        "Volume": [
            50000,
            "high"
        ],
        "marketcap": [
            5000,
            "small"
        ]
    },
    {
        "Name": "bioffoz",
        "sharia": false,
        "Volume": [
            40000,
            "moderate"
        ],
        "marketcap": [
            5000,
            "large"
        ]
    }
]

then sort by volume

[
    {
        "Name": "Infosys",
        "sharia": true,
        "Volume": [
            50000,
            "high"
        ],
        "marketcap": [
            6000,
            "large"
        ]
    },
    {
        "Name": "Hcl",
        "sharia": true,
        "Volume": [
            25000,
            "moderate"
        ],
        "marketcap": [
            5000,
            "large"
        ]
    },
    {
        "Name": "orchid",
        "sharia": true,
        "Volume": [
            200,
            "low"
        ],
        "marketcap": [
            6000,
            "Large"
        ]
    },
    {
        "Name": "hero honda",
        "sharia": true,
        "Volume": [
            150,
            "low"
        ],
        "marketcap": [
            400,
            "medium "
        ]
    },
    {
        "Name": "rado",
        "sharia": false,
        "Volume": [
            50000,
            "high"
        ],
        "marketcap": [
            5000,
            "small"
        ]
    },
    {
        "Name": "bioffoz",
        "sharia": false,
        "Volume": [
            40000,
            "moderate"
        ],
        "marketcap": [
            5000,
            "large"
        ]
    },
    {
        "Name": "sureshot",
        "sharia": false,
        "Volume": [
            20000,
            "moderate"
        ],
        "marketcap": [
            5000,
            "small"
        ]
    },
    {
        "Name": "ssinc ",
        "sharia": false,
        "Volume": [
            200,
            "low"
        ],
        "marketcap": [
            5000,
            "large"
        ]
    }
]

All Sorted:

[
    {
        "Name": "Infosys",
        "sharia": true,
        "Volume": [
            50000,
            "high"
        ],
        "marketcap": [
            6000,
            "large"
        ]
    },
    {
        "Name": "Hcl",
        "sharia": true,
        "Volume": [
            25000,
            "moderate"
        ],
        "marketcap": [
            5000,
            "large"
        ]
    },
    {
        "Name": "orchid",
        "sharia": true,
        "Volume": [
            200,
            "low"
        ],
        "marketcap": [
            6000,
            "Large"
        ]
    },
    {
        "Name": "hero honda",
        "sharia": true,
        "Volume": [
            150,
            "low"
        ],
        "marketcap": [
            400,
            "medium "
        ]
    },
    {
        "Name": "rado",
        "sharia": false,
        "Volume": [
            50000,
            "high"
        ],
        "marketcap": [
            5000,
            "small"
        ]
    },
    {
        "Name": "bioffoz",
        "sharia": false,
        "Volume": [
            40000,
            "moderate"
        ],
        "marketcap": [
            5000,
            "large"
        ]
    },
    {
        "Name": "sureshot",
        "sharia": false,
        "Volume": [
            20000,
            "moderate"
        ],
        "marketcap": [
            5000,
            "small"
        ]
    },
    {
        "Name": "ssinc ",
        "sharia": false,
        "Volume": [
            200,
            "low"
        ],
        "marketcap": [
            5000,
            "large"
        ]
    }
]
Tabraiz Ali
  • 677
  • 9
  • 36

1 Answers1

1

You will need to iterate over the fields in each comparison, when the two elements are equal by the first key go comparing by the second and so on (see it here with if-statements, and below a general solution). Also, you've got an additional complexity as some of your fields are nested (see any of these for how it works).

function sort_by_multiple(fields, reverse, primer){

    function key(x, field) {
        if (Array.isArray(field))
            for (var i=0; i<field.length; i++)
                x = x[field[i]];
        else
            x = x[field];
        return primer ? primer(x) : x;
    }

    return function (a,b) {
        for (var cmp=0, i=0; i<fields.length && cmp==0; i++) {
            var A = key(a, fields[i]), B = key(b, fields[i]);
            cmp = (A>B) - (B>A);
        }
        return reverse ? -cmp : cmp;
    }
}

Now you can do:

company.sort(sort_by_multiple(['sharia',  ['Volume',0], ['marketcap',0]], true);
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • I believe you had a typo there – Alexander Feb 23 '13 at 11:34
  • 1
    @Alexander: Still writing… and thanks for fixing :-) Is something left unclear? – Bergi Feb 23 '13 at 11:34
  • @Bergi am getting following error Uncaught ReferenceError: Invalid left-hand side in assignment on the line Array.isArray(field) && field = field.slice() – Tabraiz Ali Feb 23 '13 at 12:52
  • 1
    @TabraizAli: Yeah, you would need to use `Array.isArray(field) && (field = field.slice())` to avoid that error. In the answer I now just switched to a proper for-loop :-) – Bergi Feb 23 '13 at 16:20