0

I am trying to create a function where it takes in the key of the object needed to sort the values(in this case 'kills'). I tried using dynamicSort stated in Sort array of objects by string property value, but I'm just getting the list returned. Any ideas as to what I'm doing wrong here?

const list = [
    {
        name: 'compass',
        kills: 35,
        assists: 312
    },
    {
        name: 'another one',
        kills: 52,
        assists: 32
    },
    {
        name: 'another anothe one',
        kills: 12,
        assists: 30
    }
];

const sortByType = (property) => {
  return function (a, b) {
    let result;
    if (a[property] < b[property]) {
      result = -1;
    }
    if (a[property] > b[property]) {
      result = 1;
    }
    else {
      result = 0;
    }
    return result;
  };
}

let newList = list.sort(sortByType('kills'));
console.log(newList);

EDITED: updated how the code is being used.

Etep
  • 2,721
  • 4
  • 17
  • 28

2 Answers2

1

Hey you could just simply sort the array using the property in the sort function.

Ascending order a[property] - b[property] Descending order b[property] - a[property]

the sort by name is converting all the names into an array sorting them and then looping through to have it sorted. This runs in n^2 so it worth looking into optimizations, but this will get you across the finish line.

NOTE: this function will not work is name is undefined.

const list = [
    {
        name: 'compass',
        kills: 35,
        assists: 312
    },
    {
        name: 'another one',
        kills: 52,
        assists: 32
    },
    {
        name: 'another anothe one',
        kills: 12,
        assists: 30
    }
]


const sortByString = () => {
    const strings = list.map(prop => prop.name).sort();
    let sorted = [];
    for(const idx in strings){
        let currString = strings[idx];
        for(const objIdx in list){
            console.log(currString, list[objIdx].name)
            if(list[objIdx].name === currString){
                sorted.push(list[objIdx]);
            }
        }
    }
    return sorted;
}
const dynamicSortByType = (property) => {
    return typeof list[0][property] === 'string' ? 
    sortByString() : list.sort((a,b) => a[property] - b[property])
}
console.log(dynamicSortByType('name'))
Grant Herman
  • 923
  • 2
  • 13
  • 29
  • The method in the question should work to sort by strings. – Barmar Nov 02 '20 at 18:46
  • So one thing I added the string sort. It is running in n^2 so with really large objects it might be slow. It worth looking into optimizing. Just putting strings into an array to sort was the best option I could think of – Grant Herman Nov 02 '20 at 18:59
1

Short answer:

You're just missing the word else.

Long answer:

You have a block that looks like

if () {
}
if () {
}
else {
}

that should look like:

if () {
}
else if () {
}
else {
}

Notice the addition of the else before the second if. Without it, the second if-else will run and the final else will supersede the setting made by the truthy case of the first if.

For example, any time if (a[property] < b[property]) {, it will actually fall through the second if's else and result in setting result = 0.

Here is your snippet with the tiny repair made:

const list = [
    {
        name: 'compass',
        kills: 35,
        assists: 312
    },
    {
        name: 'another one',
        kills: 52,
        assists: 32
    },
    {
        name: 'another anothe one',
        kills: 12,
        assists: 30
    }
];

const sortByType = (property) => {
  return function (a, b) {
    let result;
    if (a[property] < b[property]) {
      result = -1;
    }
    else if (a[property] > b[property]) {  /* FIXED:  added `else` on this line */
      result = 1;
    }
    else {
      result = 0;
    }
    return result;
  };
}

let newList = list.sort(sortByType('kills'));
console.log(newList);
Wyck
  • 10,311
  • 6
  • 39
  • 60