简体   繁体   English

按 2 个值对 javascript 对象数组进行排序

[英]sorting a javascript array of objects by 2 values

I have an array of objects, and I want the selected object to always be first.我有一个对象数组,我希望选定的 object 始终排在第一位。 Then, if the object has a role === External but it's not selected, I want that to always by last.然后,如果 object 有一个role === External但它没有被选中,我希望它总是在最后。 If it doesn't match either, it's just in between the two.如果两者都不匹配,则它介于两者之间。

const exampleObj = [
  { role: 'other', selected: false },
  { role: 'External', selected: false },
  { role: 'External', selected: false },
  { role: 'other', selected: true },
  { role: 'other', selected: false },
]

This works:这有效:

  exampleObj.sort((a, b) => {
        if (!a.selected && b.selected) return 1
        if (a.selected && !b.selected) return -1
        if (!a.role !== 'External' && b.role !== 'External') return 1
        if (a.role !== 'External' && !b.role !== 'External') return -1
        return 0

But I'm getting the prettier error但我得到了更漂亮的错误

TS2367: This condition will always return 'true' since the types 'boolean' and 'string' have no overlap.
    108 |             if (!a.selected && b.selected) return 1
    109 |             if (a.selected && !b.selected) return -1
  > 110 |             if (!a.role !== 'External' && b.role !== 'External') return 1
        |                 ^^^^^^^^^^^^^^^^^^^^^^
    111 |             if (a.role !== 'External' && !b.role !== 'External') return -1
    112 |             return 0
    113 |           })

TS2367: This condition will always return 'true' since the types 'boolean' and 'string' have no overlap.
    109 |             if (a.selected && !b.selected) return -1
    110 |             if (!a.role !== 'External' && b.role !== 'External') return 1
  > 111 |             if (a.role !== 'External' && !b.role !== 'External') return -1
        |                                          ^^^^^^^^^^^^^^^^^^^^^^
    112 |             return 0
    113 |           })
    114 |         : []

But if I remove those 2 lines, it's obviously not going to push the External to the end.但是如果我删除那两行,显然不会将External推到最后。 What am I missing here?我在这里错过了什么?

You could use a.role === 'External' && b.role !== 'External' instead您可以改用a.role === 'External' && b.role !== 'External'

.a.role !== 'External' is same as false !== 'External' because .a.role will be evaluated first and the result is compared to the string. .a.role !== 'External'false !== 'External'相同,因为将首先评估.a.role并将结果与字符串进行比较。

You say !'string' which is always false.你说!'string'总是错误的。 Because the exclamation mark is casting the variable (value) to boolean and negating it.因为感叹号是将变量(值)转换为 boolean 并将其取反。 So You actually say:所以你实际上说:

false !== 'string'

Which is always true .这总是true that's why it says "This condition will always return 'true'"这就是为什么它说“这个条件将永远返回‘真’”

The.这。 before a and b string variables are the problem.在 a 和 b 字符串变量之前是问题所在。 if (.a.role !== 'External' && b.role !== 'External') return 1 evaluates to "if (true.== 'External'.... Remove those ! for if (a.role.== 'External' && b.role !== 'External') return 1 . if (.a.role !== 'External' && b.role !== 'External') return 1 evaluates to "if (true.== 'External'.... Remove those ! for if (a.role.== 'External' && b.role !== 'External') return 1

You could take a more concise approach by using deltas of the conditions.您可以通过使用条件增量来采用更简洁的方法。

 const array = [{ role: 'other', selected: false }, { role: 'External', selected: false }, { role: 'External', selected: false }, { role: 'other', selected: true }, { role: 'other', selected: false }]; array.sort((a, b) => b.selected - a.selected || (a.role === 'External' &&.a.selected) - (b.role === 'External' &&;b.selected) ); console.log(array);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM