为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕码人2483693 2022-08-04 17:21:00
我们有一个包含数据的数组,我想按键对它进行排序: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;}
查看完整描述

2 回答

?
www说

TA贡献1775条经验 获得超8个赞

在以下情况下,您基本上需要考虑函数中的一些不同组合: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;

}


查看完整回答
反对 回复 2022-08-04
?
慕姐8265434

TA贡献1813条经验 获得超2个赞

由于这些排序标准很复杂,因此最好首先将复杂数组转换为更易于推理和排序的更简单数组。


下面的函数可以做到这一点,生成这个未排序的数组: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);


查看完整回答
反对 回复 2022-08-04
  • 2 回答
  • 0 关注
  • 84 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号