简体   繁体   English

如果值存在,则对对象数组进行排序

[英]Sort array of object if value exists

Below is my sort function but I want to display the ones with a code to be at the top. 下面是我的排序功能,但我想在顶部显示代码。 I want to sort my array of objects by code, then by description. 我想按代码然后按描述对对象数组进行排序。 Right now, the items without a code is being placed at the top of the order. 现在,没有代码的项目被放置在订单的顶部。

data = [
 {
  code: "1.1",
  description: "aaa"
 },
 {
  code: "",
  description: "bbb"
 },
 {
  code: "1.2",
  description: "ccc"
 }
]


  let sortedData = data.sort(function(a, b) {
    let codeA = a.code
    let codeB = b.code
    let descriptionA = a.description.toLowerCase()
    let descriptionB = b.description.toLowerCase()

    if (codeA < codeB) return -1
    if (codeA > codeB) return 1
    if (descriptionA < descriptionB) return -1
    if (descriptionA > descriptionB) return 1
    return 0
  })

  return sortedData

Current order: 当前订单:

["bbb", "aaa", "ccc"]

Expected order: 预期订单:

["aaa", "ccc", "bbb"]

  • Using the xor ^ operator, we can check to see if one of the codes is falsy while the other is truthy. 使用xor ^运算符,我们可以检查其中一个代码是否虚假,而另一个代码是否虚假。 In this case, falsy being blank. 在这种情况下,falsy为空白。 If this is true, the one with a blank should be greater than the other so it sorts after it. 如果是这样,则一个空白的应该大于另一个,以便在其后进行排序。
  • Otherwise, subtract the codes, then the descriptions for normal sorting. 否则,请减去代码,然后再进行正常排序的说明。

 var data = [ { code: "1.1", description: "aaa" }, { code: "", description: "bbb" }, { code: "1.2", description: "ccc" } ]; let sortedData = data.sort(function(a, b) { let codeA = a.code; let codeB = b.code; let descriptionA = a.description.toLowerCase(); let descriptionB = b.description.toLowerCase(); if (codeA ^ codeB) { return !codeA ? 1 : -1; } return codeA.localeCompare(codeB) || descriptionA.localeCompare(descriptionB); }); console.log(sortedData) 

One way to make "" appear at the end is just to prefix the compare values, so if the code is "", the value becomes "B" , if it's 1.1 it become A1.1 , so A1.1 < B .. 使""出现在末尾的一种方法是在比较值前加上前缀,因此,如果代码为“”,则该值变为"B" ,如果为1.1则变为A1.1 ,因此A1.1 < B ..

Doing this is also very easy to modify to do all sort of fancy sorting, eg. 这样做也很容易修改以进行各种花式排序,例如。 Lets say you wanted to sort alphabetically, but wanted all K's at the start, and all B's at the end, strange thing to do. 假设您想按字母顺序排序,但想要所有K's开头,所有B's结尾,这很奇怪。 But very easy to make happen. 但是很容易实现。 I suppose you could call it sorting with exceptions. 我想您可以称其为例外排序。

Here is a working example. 这是一个工作示例。

 const data = [ { code: "1.1", description: "aaa" }, { code: "", description: "bbb" }, { code: "1.2", description: "ccc" } ]; data.sort(( { code: code1, description: desc1 }, { code: code2, description: desc2 } ) => { code1 = (code1 === "" ? "B" : "A") + code1; code2 = (code2 === "" ? "B" : "A") + code2; return code1.localeCompare(code2) || desc1.localeCompare(desc2); }); console.log(data); 

Your test case is a little lax and makes it hard to spot some bugs. 您的测试用例有点松懈,很难发现一些错误。 You are usually better off using localeCompare to compare strings. 通常,最好使用localeCompare比较字符串。 You can make a case for two very plain, but readable if statements followed by a localeCompare of the strings: 您可以对两个非常简单但易于理解的if语句加上字符串的localeCompare进行区分:

Here's a few extra test cases 这是一些额外的测试用例

 let data = [{ code: "1.1", description: "ddd" }, { code: "1.101", description: "ccc" }, { code: "", description: "eee" }, { code: "1.2", description: "De" }, { code: "1.1", description: "aaa" }, { code: "", description: "bbb" }, { code: "1.2", description: "ccc" }, { code: "1.2", description: "AbcD" } ] data.sort((a, b) => { if (a.code && !b.code) return -1 if (b.code && !a.code) return 1 return a.code.localeCompare(b.code) || a.description.localeCompare(b.description) }) console.log(data) 

:

Since your second code is empty you will compare an empty string and Javascript will cast your Float to a String . 由于第二个代码为空,因此您将比较一个空字符串,而Javascript会将Float转换为String Oddly if you compare any string if it is smaller than any other string it will always return true ! 奇怪的是,如果您比较任何小于任何其他字符串的字符串,它将始终返回true The opposite is also true - if you compare it to be bigger than any other string it will always return false . 反之亦然-如果您将其比较为大于任何其他字符串,它将始终返回false

"" < "1.1" // return true
"1.1" < "" // return true!

"" > "1.1" // return false
"1.1" > "" // return false!

To solve your problem you could add two additional checks before your other checks 为了解决您的问题,您可以在其他检查之前添加两个其他检查

if (codeA === "" && codeA.length < codeB.length) return 1;
if (codeB === "" && codeA.length > codeB.length) return -1;

If codeA or codeB is a String you can simply compare the length of the strings. 如果codeA或codeB是String ,则可以简单地比较字符串的长度。

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

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