如何根据几个参数对数组进行排序?

How can I sort an array based on a couple parameters?

爱好网页游戏。我有一个包含宠物的“库存”:

interface Pet {
  type: string;
  level: number;
  isFavorite: boolean;
}

allPetSlots = [
  {slotState: INVENTORY_STATE.EQUIPPED, pet: {...},
  {slotState: INVENTORY_STATE.OCCUPIED, pet: {...},
  {slotState: INVENTORY_STATE.OCCUPIED, pet: {...},
  {slotState: INVENTORY_STATE.EMPTY, pet: null,
  {slotState: INVENTORY_STATE.EMPTY, pet: null,
  {slotState: INVENTORY_STATE.EMPTY, pet: null,
  {...}
]

我目前有一种 sortAll 方法可以根据这些特定标准对库存进行排序:

  1. 最喜欢的宠物最先出现
  2. 按宠物类型分组
  3. 按级别排序
  4. 之后出现所有空白点

这是我的:

allPetsSlots
        .sort((a) => (a.state === 'occupied' || a.state === 'equipped' ? -1 : 1))
        .sort((a, b) => {
            if (a.pet?.type < b.pet?.type) return -1;
            if (a.pet?.type > b.pet?.type) return 1;
            return 0;
        })
        .sort((a, b) => {
            if (a.pet?.type === b.pet?.type && a.pet?.level > b.pet?.level) return -1;
            if (a.pet?.type === b.pet?.type && a.pet?.level < b.pet?.level) return 1;
            return 0;
        })
        .sort((a, b) => {
            if (a.pet?.isFavorite || b.pet?.isFavorite) return -1;
            return 1;
        })

虽然这个 SEEMS 在 chrome 中工作:

我在使用其他浏览器时遇到了一些问题。我很确定我的排序函数正在做一些奇怪的事情,我的大脑今天特别模糊。

非常感谢任何帮助!

const currentPets = [
  { state: 'empty', pet: null},
  { state: 'empty', pet: null},
  { state: 'empty', pet: null},
  { state: 'empty', pet: null},
  { state: 'empty', pet: null},
  { state: 'occupied', pet: { type: 'quartz', level: 2, isFavorite: false}},
  { state: 'occupied', pet: { type: 'quartz', level: 3, isFavorite: false}},
  { state: 'equipped', pet: { type: 'quartz', level: 6, isFavorite: true}},
  { state: 'occupied', pet: { type: 'quartz', level: 2, isFavorite: false}},
  { state: 'occupied', pet: { type: 'obsidian', level: 2, isFavorite: false}},
  { state: 'occupied', pet: { type: 'obsidian', level: 5, isFavorite: false}},
  { state: 'occupied', pet: { type: 'obsidian', level: 6, isFavorite: true}},
  { state: 'empty', pet: null},
  { state: 'empty', pet: null},
  { state: 'occupied', pet: { type: 'agate', level: 1, isFavorite: false}},
  { state: 'occupied', pet: { type: 'agate', level: 2, isFavorite: false}},
  { state: 'occupied', pet: { type: 'agate', level: 4, isFavorite: true}},
]

const sortAll = () => {
  currentPets
    .sort((a) => (a.state === 'occupied' || a.state === 'equipped' ? -1 : 1))
        .sort((a, b) => {
            if (a.pet?.type < b.pet?.type) return -1;
            if (a.pet?.type > b.pet?.type) return 1;
            return 0;
        })
        .sort((a, b) => {
            if (a.pet?.type === b.pet?.type && a.pet?.level > b.pet?.level) return -1;
            if (a.pet?.type === b.pet?.type && a.pet?.level < b.pet?.level) return 1;
            return 0;
        })
        .sort((a, b) => {
            if (a.pet?.isFavorite || b.pet?.isFavorite) return -1;
            return 0;
        })
}

console.log('sorted', currentPets)

您需要考虑 undefined。我认为对一个数组进行多次排序是一种资源浪费,因为排序需要很多循环。

我只为您更改了 isFavorite 排序。如果我是你,我会在第一个选中的 属性 (isFavorite) 下继续使用更多代码。

const currentPets = [
  { state: 'empty', pet: null},
  { state: 'empty', pet: null},
  { state: 'empty', pet: null},
  { state: 'empty', pet: null},
  { state: 'empty', pet: null},
  { state: 'occupied', pet: { type: 'quartz', level: 2, isFavorite: false}},
  { state: 'occupied', pet: { type: 'quartz', level: 3, isFavorite: false}},
  { state: 'equipped', pet: { type: 'quartz', level: 6, isFavorite: true}},
  { state: 'occupied', pet: { type: 'quartz', level: 2, isFavorite: false}},
  { state: 'occupied', pet: { type: 'obsidian', level: 2, isFavorite: false}},
  { state: 'occupied', pet: { type: 'obsidian', level: 5, isFavorite: false}},
  { state: 'occupied', pet: { type: 'obsidian', level: 6, isFavorite: true}},
  { state: 'empty', pet: null},
  { state: 'empty', pet: null},
  { state: 'occupied', pet: { type: 'agate', level: 1, isFavorite: false}},
  { state: 'occupied', pet: { type: 'agate', level: 2, isFavorite: false}},
  { state: 'occupied', pet: { type: 'agate', level: 4, isFavorite: true}},
]


const sortAll = () => {
  let tempA, tempB;

  return currentPets
    .sort((a, b) => {
        tempA = a.pet?.isFavorite
        tempB = b.pet?.isFavorite

        // you should refactor this if statement
        if (tempA !== tempB) {
          if (typeof tempA == 'undefined') { return 1  }
          if (typeof tempB == 'undefined') { return -1 }
          if (tempA < tempB)               { return 1  }
          if (tempA > tempB)               { return -1 }
        }

        // tempA = a.pet?.type
        // tempB = b.pet?.type
        //if (tempA !== tempB) {
          // ...
        //}

        return 0
    })
}

console.log('sorted', sortAll());

重构代码后它应该是什么样子:

const currentPets = [
  { state: 'empty', pet: null},
  { state: 'empty', pet: null},
  { state: 'empty', pet: null},
  { state: 'empty', pet: null},
  { state: 'empty', pet: null},
  { state: 'occupied', pet: { type: 'quartz', level: 2, isFavorite: false}},
  { state: 'occupied', pet: { type: 'quartz', level: 3, isFavorite: false}},
  { state: 'equipped', pet: { type: 'quartz', level: 6, isFavorite: true}},
  { state: 'occupied', pet: { type: 'quartz', level: 2, isFavorite: false}},
  { state: 'occupied', pet: { type: 'obsidian', level: 2, isFavorite: false}},
  { state: 'occupied', pet: { type: 'obsidian', level: 5, isFavorite: false}},
  { state: 'occupied', pet: { type: 'obsidian', level: 6, isFavorite: true}},
  { state: 'empty', pet: null},
  { state: 'empty', pet: null},
  { state: 'occupied', pet: { type: 'agate', level: 1, isFavorite: false}},
  { state: 'occupied', pet: { type: 'agate', level: 2, isFavorite: false}},
  { state: 'occupied', pet: { type: 'agate', level: 4, isFavorite: true}},
]


const sortAll = (arr) => {
  const UNSORTED = 0;
  let   result   = 0;

  return arr
    .sort((a, b) => {
        result = compareProperties(a.pet?.isFavorite, b.pet?.isFavorite)

        // if (result == UNSORTED) {
        //  result = compareProperties(a.pet?.type, b.pet?.type)
        // }
        
        // if (result == UNSORTED) {
        // ...

        return result
    })
}

const compareProperties = (tempA, tempB) => {
  if (tempA !== tempB) {
    if (typeof tempA == 'undefined') { return 1  }
    if (typeof tempB == 'undefined') { return -1 }
    if (tempA < tempB)               { return 1  }
    if (tempA > tempB)               { return -1 }
  }

  return 0
}

console.log('sorted', sortAll(currentPets));