1

I am trying to sort a complex object based off of a specific key placement. That key is usually either a numerical values 1, 2, 3, etc. It can also indicate a tie by having 1T, 2T, 3T, etc. But, if a team did not finish or was disqualified, their placement will be marked as DQ or DNF. I want any team with placement == DQ || placement == DNF to be sorted at the end of the list.

The object looks like this:

placements = {
        "c111c16d-8132-11eb-8fe2-0800273120f7": {
          "team": "St Olaf",
          "team_location": null,
          "team_season_id": "c111c16d-8132-11eb-8fe2-0800273120f7",
          "event_team_placement_id": 8343,
          "seed": "8",
          "placement": "DNF",
          "spirit_score": "12.33",
          "won_spirit_tie_breaker": null,
          "won_spirit": null
        },
        "c118f96a-8132-11eb-8fe2-0800273120f7": {
          "team": "Bates",
          "team_location": null,
          "team_season_id": "c118f96a-8132-11eb-8fe2-0800273120f7",
          "event_team_placement_id": 8344,
          "seed": "12",
          "placement": "1",
          "spirit_score": "14.20",
          "won_spirit_tie_breaker": null,
          "won_spirit": null
        },
        "c14b9603-8132-11eb-8fe2-0800273120f7": {
          "team": "Puget Sound",
          "team_location": null,
          "team_season_id": "c14b9603-8132-11eb-8fe2-0800273120f7",
          "event_team_placement_id": 8352,
          "seed": "2",
          "placement": "3T",
          "spirit_score": "11.83",
          "won_spirit_tie_breaker": null,
          "won_spirit": null
        },
        "c1459d8c-8132-11eb-8fe2-0800273120f7": {
          "team": "Lehigh",
          "team_location": null,
          "team_season_id": "c1459d8c-8132-11eb-8fe2-0800273120f7",
          "event_team_placement_id": 8351,
          "seed": "0",
          "placement": "3T",
          "spirit_score": "9.80",
          "won_spirit_tie_breaker": null,
          "won_spirit": null
        },
        "c164df69-8132-11eb-8fe2-0800273120f7": {
          "team": "Williams",
          "team_location": null,
          "team_season_id": "c164df69-8132-11eb-8fe2-0800273120f7",
          "event_team_placement_id": 8356,
          "seed": "2",
          "placement": "5T",
          "spirit_score": "13.25",
          "won_spirit_tie_breaker": null,
          "won_spirit": null
        },
        "c15e97ae-8132-11eb-8fe2-0800273120f7": {
          "team": "Wesleyan",
          "team_location": null,
          "team_season_id": "c15e97ae-8132-11eb-8fe2-0800273120f7",
          "event_team_placement_id": 8355,
          "seed": "5",
          "placement": "5T",
          "spirit_score": "10.50",
          "won_spirit_tie_breaker": null,
          "won_spirit": null
        },
        "c15866e0-8132-11eb-8fe2-0800273120f7": {
          "team": "Rensselaer Polytech",
          "team_location": null,
          "team_season_id": "c15866e0-8132-11eb-8fe2-0800273120f7",
          "event_team_placement_id": 8354,
          "seed": "8",
          "placement": "5T",
          "spirit_score": "14.80",
          "won_spirit_tie_breaker": null,
          "won_spirit": null
        },
        "c151d3f9-8132-11eb-8fe2-0800273120f7": {
          "team": "Mount Holyoke",
          "team_location": null,
          "team_season_id": "c151d3f9-8132-11eb-8fe2-0800273120f7",
          "event_team_placement_id": 8353,
          "seed": "12",
          "placement": "5T",
          "spirit_score": "11.60",
          "won_spirit_tie_breaker": null,
          "won_spirit": null
        },
      }

and my current function to sort it:

sortByFinish(): void{
      let sorted = this.placements.sort(
        (a,b) => (parseInt(a.placement) - parseInt(b.placement))
      )
      this.placements = sorted
  }

This works for any placement that is numerical or has a tie, but it does not work when the placement is DQ or DNF. How can I handle those cases so they sorted at the end of the list?

bmorgs
  • 195
  • 1
  • 12

3 Answers3

2

You can't just sort items in an object as you did in pure JS. First, you have to make an array of the results like it's shown in this answer.

const sortable = Object.entries(placements);

When sorting the placements, you don't have to deal with those that match DQ or DNF. I'd simply take them out from the source, and add them into it later. You can use several array partitioning methods, but to keep it simple and clean I'll use two filters to figure out which entries are needed to be sort (it might not be the most efficient way).

Object.entries returns the object's entries as arrays, where the first element is the key, and the second is the value. We need to add those indexes to your sorting function.

Full code:

const placements = {
    "c111c16d-8132-11eb-8fe2-0800273120f7": {
        "team": "St Olaf",
        "team_location": null,
        "team_season_id": "c111c16d-8132-11eb-8fe2-0800273120f7",
        "event_team_placement_id": 8343,
        "seed": "8",
        "placement": "DNF",
        "spirit_score": "12.33",
        "won_spirit_tie_breaker": null,
        "won_spirit": null
    },
    "c118f96a-8132-11eb-8fe2-0800273120f7": {
        "team": "Bates",
        "team_location": null,
        "team_season_id": "c118f96a-8132-11eb-8fe2-0800273120f7",
        "event_team_placement_id": 8344,
        "seed": "12",
        "placement": "1",
        "spirit_score": "14.20",
        "won_spirit_tie_breaker": null,
        "won_spirit": null
    },
    "c14b9603-8132-11eb-8fe2-0800273120f7": {
        "team": "Puget Sound",
        "team_location": null,
        "team_season_id": "c14b9603-8132-11eb-8fe2-0800273120f7",
        "event_team_placement_id": 8352,
        "seed": "2",
        "placement": "3T",
        "spirit_score": "11.83",
        "won_spirit_tie_breaker": null,
        "won_spirit": null
    },
    "c1459d8c-8132-11eb-8fe2-0800273120f7": {
        "team": "Lehigh",
        "team_location": null,
        "team_season_id": "c1459d8c-8132-11eb-8fe2-0800273120f7",
        "event_team_placement_id": 8351,
        "seed": "0",
        "placement": "3T",
        "spirit_score": "9.80",
        "won_spirit_tie_breaker": null,
        "won_spirit": null
    },
    "c164df69-8132-11eb-8fe2-0800273120f7": {
        "team": "Williams",
        "team_location": null,
        "team_season_id": "c164df69-8132-11eb-8fe2-0800273120f7",
        "event_team_placement_id": 8356,
        "seed": "2",
        "placement": "5T",
        "spirit_score": "13.25",
        "won_spirit_tie_breaker": null,
        "won_spirit": null
    },
    "c15e97ae-8132-11eb-8fe2-0800273120f7": {
        "team": "Wesleyan",
        "team_location": null,
        "team_season_id": "c15e97ae-8132-11eb-8fe2-0800273120f7",
        "event_team_placement_id": 8355,
        "seed": "5",
        "placement": "5T",
        "spirit_score": "10.50",
        "won_spirit_tie_breaker": null,
        "won_spirit": null
    },
    "c15866e0-8132-11eb-8fe2-0800273120f7": {
        "team": "Rensselaer Polytech",
        "team_location": null,
        "team_season_id": "c15866e0-8132-11eb-8fe2-0800273120f7",
        "event_team_placement_id": 8354,
        "seed": "8",
        "placement": "5T",
        "spirit_score": "14.80",
        "won_spirit_tie_breaker": null,
        "won_spirit": null
    },
    "c151d3f9-8132-11eb-8fe2-0800273120f7": {
        "team": "Mount Holyoke",
        "team_location": null,
        "team_season_id": "c151d3f9-8132-11eb-8fe2-0800273120f7",
        "event_team_placement_id": 8353,
        "seed": "12",
        "placement": "5T",
        "spirit_score": "11.60",
        "won_spirit_tie_breaker": null,
        "won_spirit": null
    },
}

const sortable = Object.entries(placements);

const ignoredPlacements = ['DQ', 'DNF'];
const relevantEntries = sortable.filter(entry => ignoredPlacements.indexOf(entry[1].placement) == -1)
const irrelevantEntries = sortable.filter(entry => ignoredPlacements.indexOf(entry[1].placement) != -1)

let sorted = relevantEntries.sort((a,b) => (parseInt(a[1].placement) - parseInt(b[1].placement)));
sorted = [...sorted, irrelevantEntries];

console.log(sorted);
Hasip Timurtas
  • 983
  • 2
  • 11
  • 20
blckdg
  • 36
  • 3
  • Thank you! The trick was to filter out those irrelevant items, sort the rest, and the add them at the end. – bmorgs Mar 14 '21 at 03:38
0

Placements is an object, not an array. Sort function works in array.

Here is how I have solved it. It might help.

const sortByFinish = (placements) => {
  let values = Object.values(placements);
  let sorted = values
    .filter((value) => !isNaN(parseInt(value.placement, 10)))
    .sort((a, b) => parseInt(a.placement, 10) - parseInt(b.placement, 10));

    sorted = sorted.concat(values.filter(value => isNaN(parseInt(value.placement, 10))))
  console.log(sorted);
};

Here we have filtered numeric values first then we have concat non numeric value.

Jitesh Manglani
  • 495
  • 5
  • 12
0

You can modify the logic of your callback function of the sort method like below to get the result that you need. This will work properly if you don't care about the sort order of your non-numeric placement values. Those will be sorted alphabetically at the bottom of the array.

placements = {
        "c111c16d-8132-11eb-8fe2-0800273120f7": {
          "team": "St Olaf",
          "team_location": null,
          "team_season_id": "c111c16d-8132-11eb-8fe2-0800273120f7",
          "event_team_placement_id": 8343,
          "seed": "8",
          "placement": "DNF",
          "spirit_score": "12.33",
          "won_spirit_tie_breaker": null,
          "won_spirit": null
        },
        "c118f96a-8132-11eb-8fe2-0800273120f7": {
          "team": "Bates",
          "team_location": null,
          "team_season_id": "c118f96a-8132-11eb-8fe2-0800273120f7",
          "event_team_placement_id": 8344,
          "seed": "12",
          "placement": "1",
          "spirit_score": "14.20",
          "won_spirit_tie_breaker": null,
          "won_spirit": null
        },
        "c14b9603-8132-11eb-8fe2-0800273120f7": {
          "team": "Puget Sound",
          "team_location": null,
          "team_season_id": "c14b9603-8132-11eb-8fe2-0800273120f7",
          "event_team_placement_id": 8352,
          "seed": "2",
          "placement": "3T",
          "spirit_score": "11.83",
          "won_spirit_tie_breaker": null,
          "won_spirit": null
        },
        "c1459d8c-8132-11eb-8fe2-0800273120f7": {
          "team": "Lehigh",
          "team_location": null,
          "team_season_id": "c1459d8c-8132-11eb-8fe2-0800273120f7",
          "event_team_placement_id": 8351,
          "seed": "0",
          "placement": "3T",
          "spirit_score": "9.80",
          "won_spirit_tie_breaker": null,
          "won_spirit": null
        },
        "c164df69-8132-11eb-8fe2-0800273120f7": {
          "team": "Williams",
          "team_location": null,
          "team_season_id": "c164df69-8132-11eb-8fe2-0800273120f7",
          "event_team_placement_id": 8356,
          "seed": "2",
          "placement": "11T",
          "spirit_score": "13.25",
          "won_spirit_tie_breaker": null,
          "won_spirit": null
        },
        "c15e97ae-8132-11eb-8fe2-0800273120f7": {
          "team": "Wesleyan",
          "team_location": null,
          "team_season_id": "c15e97ae-8132-11eb-8fe2-0800273120f7",
          "event_team_placement_id": 8355,
          "seed": "5",
          "placement": "5T",
          "spirit_score": "10.50",
          "won_spirit_tie_breaker": null,
          "won_spirit": null
        },
        "c15866e0-8132-11eb-8fe2-0800273120f7": {
          "team": "Rensselaer Polytech",
          "team_location": null,
          "team_season_id": "c15866e0-8132-11eb-8fe2-0800273120f7",
          "event_team_placement_id": 8354,
          "seed": "8",
          "placement": "5T",
          "spirit_score": "14.80",
          "won_spirit_tie_breaker": null,
          "won_spirit": null
        },
        "c151d3f9-8132-11eb-8fe2-0800273120f7": {
          "team": "Mount Holyoke",
          "team_location": null,
          "team_season_id": "c151d3f9-8132-11eb-8fe2-0800273120f7",
          "event_team_placement_id": 8353,
          "seed": "12",
          "placement": "5T",
          "spirit_score": "11.60",
          "won_spirit_tie_breaker": null,
          "won_spirit": null
        },
      };
      
const sortByFinish = (placements) => {
  let values = Object.values(placements);
  let sorted = values.sort((a, b) => {
    const exceptions = ['DNF', 'DQ'];
    if(exceptions.includes(a.placement) || exceptions.includes(b.placement)) return -1;
    return parseInt(a.placement) - parseInt(b.placement);
  });
  console.log(sorted);
};

sortByFinish(placements);
farhodius
  • 510
  • 3
  • 8