Home > Net >  Sort an array of different values in JavaScript
Sort an array of different values in JavaScript

Time:08-09

I have a use case where I need to sort two different lots of values in the same go. Basically, I'm building a Lightning Web Component and need to display a list of records with these sorting requirements:

  1. All initial empty records with Name set as "Patient" to ALWAYS sit at the top.
  2. All saved records moved to the BOTTOM of the list and sorted alphabetically (The LastName and UniqueNumber fields will be automatically assigned to the Name field so will replace "Patient" e.g. "Smith 12345").
  3. All records set to "Abandoned" status moved to the BOTTOM of the list, even below the saved records from the above step.

I have achieved steps 1 and 2 by using this code in my wire service:

records.sort((a, b) => {
    if(a.fields.Name.value === "Patient") return -1;
    if(b.fields.Name.value === "Patient") return 1;
    return a.fields.Name.value.localeCompare(b.fields.Name.value);
});

What I'm missing is the sorting of the Status field when it is set to "Abandoned". Is there a way I can include the needed logic in my current JavaScript code to always have these records at the bottom of the list no matter what?

This is what it's looking like so far, the empty "Patient" records are sitting at the top, but am missing the capability to move "Abandoned" records below everything else, even though I still want the saved records to be alphabetically ordered (like they are currently).

enter image description here

[
  {
     fields: {
       Name: {
         value: "Patient" 
       },
       Status: {
         value: "Abandoned"
       }
     }
  }
]

CodePudding user response:

Since the first rule state that "Patient" must be on top, I assumed "Patient-Abandoned" should be on top of "John-On Hold".
I think the code readability would be improved by some flag that store the result of basic checks (i.e. aIsPatient and aIsAbandoned).
That said the first check should be on "Patient" name, as you already did, then you should add a check on "Abandoned" status, first on b, then on a and finally the localeCompare on name.
Therefore the code will look like this:

records.sort((a, b) => {
    const aIsPatient = a.fields.Name.value === "Patient";
    const aIsAbandoned = a.fields.Status.value === "Abandoned";
    const bIsPatient = b.fields.Name.value === "Patient";
    const bIsAbandoned = b.fields.Status.value === "Abandoned";
    if (aIsPatient) {
        if (bIsPatient) {
            return bIsAbandoned || !aIsAbandoned ? -1 : 1;
        }
        return -1;
    }
    if (bIsPatient) {
        return 1;
    }
    if (bIsAbandoned) {
        return -1;
    }
    if (aIsAbandoned) {
        return 1;
    }
    return a.fields.Name.value.localeCompare(b.fields.Name.value);
});

You could test it with this snippet:

let records = [
  {
     fields: {
       Name: {
         value: "Patient" 
       },
       Status: {
         value: "Draft"
       }
     }
  },
  {
     fields: {
       Name: {
         value: "John" 
       },
       Status: {
         value: "Abandoned"
       }
     }
  },
  {
     fields: {
       Name: {
         value: "Smith" 
       },
       Status: {
         value: "On Hold"
       }
     }
  },
  {
     fields: {
       Name: {
         value: "Gregg" 
       },
       Status: {
         value: "Active"
       }
     }
  },
  {
     fields: {
       Name: {
         value: "Patient" 
       },
       Status: {
         value: "Abandoned"
       }
     }
  },
  {
     fields: {
       Name: {
         value: "Patient" 
       },
       Status: {
         value: "Draft"
       }
     }
  }
];

records.sort((a, b) => {
    const aIsPatient = a.fields.Name.value === "Patient";
    const aIsAbandoned = a.fields.Status.value === "Abandoned";
    const bIsPatient = b.fields.Name.value === "Patient";
    const bIsAbandoned = b.fields.Status.value === "Abandoned";
    if (aIsPatient) {
        if (bIsPatient) {
            return bIsAbandoned || !aIsAbandoned ? -1 : 1;
        }
        return -1;
    }
    if (bIsPatient) {
        return 1;
    }
    if (bIsAbandoned) {
        return -1;
    }
    if (aIsAbandoned) {
        return 1;
    }
    return a.fields.Name.value.localeCompare(b.fields.Name.value);
});

console.log(records.map((elem) => {
    return {
        name: elem.fields.Name.value,
        status: elem.fields.Status.value
    };
}));

CodePudding user response:

var chars = this.state.characters;

chars = _.orderBy(chars, ['name'],['asc']); // Use Lodash to sort array by 'name'

this.setState({characters: chars})

Check above sample code using lodash

Source : https://stackoverflow.com/a/43371146/5871092

  • Related