简体   繁体   中英

sort json ignoring blank values

I've got the following JSON data:

var json = [{ "name":"A", "value":"valueA"},
{ "name":" ", "value":"VALUES"},
{ "name":"Z", "value":"values"},
{ "name":" ", "value":"VALUES12"},
{ "name":" ", "value":"VALUES123"},
{ "name":"B", "value":"valueBS"},
{ "name":" ", "value":"VALUES123"}];

I want to sort the data alphabetically but keep the empty name values in the same position after the non-empty name . so the expected output would be:

[{ "name":"A", "value":"valueA"},
{ "name":" ", "value":"VALUES"},
{ "name":"B", "value":"valueBS"},
{ "name":" ", "value":"VALUES123"},
{ "name":"Z", "value":"values"},
{ "name":" ", "value":"VALUES12"},
{ "name":" ", "value":"VALUES123"}]

I've tried the following method

function sortResults(prop, asc, array) {
    arr = array.sort(function(a, b) {
        if (asc) return (a[prop] > b[prop]);
        else return (b[prop] > a[prop]);
    });
    return arr;
}

and called it in the following way

var sorted = sortResults('name', true, json);

This does sort the array but the blanks are also reordered which I do not want. What is the best way to fix this?

NOTE: I cannot change the JSON data order from the server as I do not have access to it.

You can trying to do it by using high order function . Moreover, you can reduce your data in order to sort your field, and then map the result.

By using high order function, your code will be more reusable. So, we will perform a map and reduce transformation.

  var json = [
    { "name":"A", "value":"valueA"},
    { "name":" ", "value":"VALUES"},
    { "name":"Z", "value":"values"},
    { "name":" ", "value":"VALUES12"},
    { "name":" ", "value":"VALUES123"},
    { "name":"B", "value":"valueBS"},
    { "name":" ", "value":"VALUES123"}
  ];

  //Create a generator function in order to sort by specifing key
  function sortBy(key){
    return function(a, b) {
      return a[key] < b[key]?-1:(a[key] > b[key])?1:0;
    }
  }

  function sorting(json){

    //Reduce my json data and start with empty array
    var sorted = json.reduce(function(result, current){
      return current.name !== ' '
      //Build a sorted array
      ? result.concat(current).sort(sortBy('name'))
      //Return current sorted array
      : result
    }, []);

    return json.map(function(elm, index, self){
      return elm.name !== ' '
      //Retrieve the first element of sorted array by shifting it
      ? sorted.shift()
      //Then, retrieve current elm in json array
      : elm
    });

  }

  console.log(sorting(json));

Iterate your JSON by checking blank names .

  1. Take the index position.
  2. Remove it from JSON array.
  3. Sort remaining JSON array.
  4. Push blank values in respective index positions.

Done!

You could consider grouping the values by adding a third field prior to sorting.

eg Start the group at 0, loop over the array setting the group field, increment it when you detect the next non-blank.

Then i guess you could apply a second sort (by group) after the first sort.

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