使用复杂/动态条件(升序和降序)对包含对象的数组进行排序?

我们有一个包含数据的数组,我想按键对它进行排序:users

  • 如果有1个对象,我按其属性排序。usersname

  • 如果有多个条目,我按 排序。usersusers.length

例:

DESCENDING: Zorya, Gorya, Dorya, Borya, Aorya, 4, 2, 0

 ASCENDING: Aorya, Borya, Dorya, Gorya, Zorya, 2, 4, 0

这是我到目前为止所做的:

const array = [{

  name: "qw",

  users: [

    { name: "Borya" },

  ],

}, {

  name: "qw",

  users: [

    { name: "Gorya" },

  ],

}, {

  name: "qw",

  users: [

   { name: "Zorya" },

 ]

}, {

  name: "qw",

  users: [

    { name: "Var" },

    { name: "Var2" },

  ],

}, {

  name: "qw",

  users: [],

}, {

  name: "qw",

  users: [

    { name: "Aorya" },

  ],

}, {

  name: "qw",

  users: [

    { name: "rwerwerwe" },

    { name: "tregdf" },

    { name: "gdfgdf" },

    { name: "Vayetrtertrr2" },

  ]

}, {

  name: "qw",

  users: [

   { name: "Dorya" },

  ],

}];


function orderCustomBy(collection, key, direction) {

  const direct = direction === "desc" ? -1 : 1;

  

  let compare = (a, b) => {

    if (a === null) return -1;

    if (b === null) return 1;

    // Just commenting this out because there's no `intlCollator` in here:

    // return intlCollator.compare(a, b);

  };

  

  if (key === "users") {

    compare = (a, b) => {

      // What should go in here?

      // intlCollator.compare(a[0].name, b[0].name);

      

      return 1;

    };

  }

  

  return [].concat(collection).sort((a, b) => {

    const result = compare(a[key], b[key]);

    return result * direct;

  });

}


console.log(orderCustomBy(array, 'users', 'asc')

  .map(item => item.users.length === 1 ? item.users[0].name : item.users.length));

  

console.log(orderCustomBy(array, 'users', 'desc')

  .map(item => item.users.length === 1 ? item.users[0].name : item.users.length));

.as-console-wrapper {

  max-height: 100% !important;

}


慕码人2483693
浏览 85回答 2
2回答

www说

在以下情况下,您基本上需要考虑函数中的一些不同组合:comparekey === 'users两者都有一个用户,因此我们比较。user[0].name只有一个用户,所以在 .aab只有一个用户,所以在 .bba没有一个有单个用户,所以我们只是比较。users.length它看起来像这样:if (a.users.length === 1 && b.users.length === 1) {  // If both have a single user, sort by users[0].name:  return a.users[0].name.localeCompare(b.users[0].name);} else if (a.users.length === 1) {  // If only `a` has a single user, `a` goes before `b`:  return -1;} else if (b.users.length === 1) {  // If only `b` has a single user, `b` goes before `a`:  return 1;}// Otherwise, sort by users.length:return a.users.length - b.users.length;在这里,您可以看到它的实际效果:const array = [{  name: "qw",  users: [    { name: "Borya" },  ],}, {  name: "qw",  users: [    { name: "Gorya" },  ],}, {  name: "qw",  users: [   { name: "Zorya" }, ]}, {  name: "qw",  users: [    { name: "Var" },    { name: "Var2" },  ],}, {  name: "qw",  users: [],}, {  name: "qw",  users: [    { name: "Aorya" },  ],}, {  name: "qw",  users: [    { name: "rwerwerwe" },    { name: "tregdf" },    { name: "gdfgdf" },    { name: "Vayetrtertrr2" },  ]}, {  name: "qw",  users: [   { name: "Dorya" },  ],}];function orderCustomBy(collection, key, direction) {  const direct = direction === "desc" ? -1 : 1;    let compare;    if (key === "users") {    compare = (a, b) => {      if (a.users.length === 1 && b.users.length === 1) {        // If both have a single user, sort by users[0].name:        return a.users[0].name.localeCompare(b.users[0].name);      } else if (a.users.length === 1) {        // If only `a` has a single user, `a` goes before `b`:        return -1;      } else if (b.users.length === 1) {        // If only `b` has a single user, `b` goes before `a`:        return 1;      }            // Otherwise, sort by users.length:      return a.users.length - b.users.length;    };  } else {    compare = (a, b) => {      if (a === null) return -1;      if (b === null) return 1;      // Just commenting this out because there's no `intlCollator` in here:      // return intlCollator.compare(a, b);    };  }    return [].concat(collection).sort((a, b) => compare(a, b) * direct);}console.log(orderCustomBy(array, 'users', 'asc')  .map(item => item.users.length === 1 ? item.users[0].name : item.users.length));  console.log(orderCustomBy(array, 'users', 'desc')  .map(item => item.users.length === 1 ? item.users[0].name : item.users.length));.as-console-wrapper {  max-height: 100% !important;}

慕姐8265434

由于这些排序标准很复杂,因此最好首先将复杂数组转换为更易于推理和排序的更简单数组。下面的函数可以做到这一点,生成这个未排序的数组:simplifyArray()[ "Borya", "Gorya", "Zorya", "2", "0", "Aorya", "4", "Dorya" ]排序它应该很简单。function simplifyArray (arr) {  return arr.map(el => {    let length = el.users.length;    if (length === 1) { return el.users[0].name; }    else return String(length);  });}const array = [{    name: "qw",    users: [      { name: "Borya" }    ]  },  {    name: "qw",    users: [      { name: "Gorya" }    ]  },  {    name: "qw",    users: [     { name: "Zorya" }   ]  },  {    name: "qw",    users: [      { name: "Var" },      { name: "Var2" }    ]  },  {    name: "qw",    users: []  },  {    name: "qw",    users: [      { name: "Aorya" }    ]  },  {    name: "qw",    users: [      { name: "rwerwerwe" },      { name: "tregdf" },      { name: "gdfgdf" },      { name: "Vayetrtertrr2" }    ]  },  {    name: "qw",    users: [     { name: "Dorya" }    ]  },];const simplerArray = simplifyArray(array);console.log(simplerArray);
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript