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

时间:2019-02-12 22:47:46

标签: javascript

下面是我的排序功能,但我想在代码顶部显示那些。我想按代码然后按描述对对象数组进行排序。现在,没有代码的商品被放置在订单的顶部。

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

当前订单:

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

预期订单:

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

4 个答案:

答案 0 :(得分:3)

  • 使用xor ^运算符,我们可以检查其中一个代码是否虚假,而另一个代码是否虚假。在这种情况下,falsy为空白。如果是这样,则其中一个空白应大于另一个,以便在其后进行排序。
  • 否则,请减去代码,然后减去常规排序的说明。

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)

答案 1 :(得分:1)

使""出现在末尾的一种方法是给比较值加上前缀,因此,如果代码为“”,则值变为"B",如果为1.1,则变为A1.1,所以A1.1 <B ..

这样做也很容易修改以进行各种花式排序,例如。假设您想按字母顺序进行排序,但是想要所有K's开头,而所有B's结尾,这很奇怪。但是很容易实现。我想您可以称其为例外排序。

这是一个可行的示例。

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);

答案 2 :(得分:1)

您的测试用例有点松懈,很难发现一些错误。通常最好使用localeCompare比较字符串。您可以为两个非常简单但易读的if语句以及后面的localeCompare个字符串做个案例:

这里有一些额外的测试用例

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)

答案 3 :(得分:0)

由于第二个代码为空,因此您将比较一个空字符串,而Javascript会将您的Float转换为String。奇怪的是,如果您比较任何小于任何其他字符串的字符串,它将始终返回true!反之亦然-如果您比较它比任何其他字符串大,它将始终返回false

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

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

要解决您的问题,您可以在其他检查之前添加另外两个检查

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

如果codeA或codeB是String,则只需比较字符串的长度即可。