对对象数组进行排序,但是第一位是固定的

时间:2019-02-20 16:08:55

标签: javascript sorting

这是一个示例,该对象带有要排序的数组:

11

我想将{ first: 'Zangief', second: 'Cammy' names: [ {name: 'Dee Jay'}, {name: 'Zangief'}, {name: 'Dhalsim'} {name: 'Chun-Li'}, {name: 'Blanka'}, {name: 'Cammy'} ] } 放在第一位,将Zangief放在第二位,其余按字母顺序排列。

预期结果:

Cammy

我知道这会按字母顺序对名称进行排序:

[
    {name: 'Zangief'},
    {name: 'Cammy'},
    {name: 'Blanka'}
    {name: 'Chun-Li'},
    {name: 'Dee Jay'},
    {name: 'Dhalsim'},
]

然后我可以找到两个名称并将它们放在前两个位置,但是有一个排序功能,排序时可以做什么?

4 个答案:

答案 0 :(得分:1)

您可能只需将函数修改为类似的内容即可

obj.names.sort((a,b) => {
    if (a.name === obj.first || (a.name === obj.second && b.name !== obj.first)){
        return -1;
    }
    return (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0);
});

答案 1 :(得分:0)

您可以使用已知名称和未知名称的顺序构建对象,并取值进行排序。

如果值相同,则按字符串排序。

var object = { first: 'Zangief', second: 'Cammy', names: [{ name: 'Dee Jay' }, { name: 'Zangief' }, { name: 'Dhalsim' }, { name: 'Chun-Li' }, { name: 'Blanka' }, { name: 'Cammy' }] },
    order = Object.assign(
        ...['first', 'second', ''].map((k, i) => ({ [object[k]]: i + 1 }))
    );

object.names.sort(({ name: a }, { name: b }) =>
    (order[a] || order.undefined) - (order[b] || order.undefined) || a.localeCompare(b)
);

console.log(object.names);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:0)

这是我的2美分。我认为对特殊 名称的名称进行硬编码是不明智的。我会在您的数组中添加一个 order ,这将导致排序覆盖其默认顺序。因此,您将不需要两个属性第一个第二个。如果您不能修改原始数组,那么也许其他答案之一更合适。

let object = {
    names: [
        { name: 'Dee Jay' },
        { name: 'Zangief', order: 1 },
        { name: 'Dhalsim' },
        { name: 'Chun-Li' },
        { name: 'Blanka' },
        { name: 'Cammy', order: 2 }
    ]
}

object.names.sort((a, b) => {
    return (a.order || Number.MAX_SAFE_INTEGER) - (b.order || Number.MAX_SAFE_INTEGER) 
           || a.name.localeCompare(b.name);

});

object.names.forEach(entry => console.log(entry.name));

另一种可能性,即使我不太喜欢它是在 new sort 之前对数组进行预处理。像这样:

object.names.find( entry => entry.name === 'Zangief' ).order = 1;
object.names.find( entry => entry.name === 'Cammy' ).order = 2;
object.names.sort( /* new sort */ );

,并添加了适当的错误检查。再说一次,我不喜欢这样,但是有可能。

答案 3 :(得分:0)

    let obj = {
      first: 'Zangief',
      second: 'Cammy',

      names: [
        {name: 'Dee Jay'},
        {name: 'Zangief'},
        {name: 'Dhalsim'},
        {name: 'Chun-Li'},
        {name: 'Blanka'},
        {name: 'Cammy'}
      ]
    };

    obj.names.sort((a,b) => {
      // exit early, (or trigger error if it should never happen)
      if (a.name === b.name) return 0;

      // No matter what, 'Zangief' gets moved to the front.
      if (a.name === obj.first) return -1;
      if (b.name === obj.first) return 1;

      // if no Zangief, 'Cammy' always moves forward.
      if (a.name === obj.second) return -1;
      if (b.name === obj.second) return 1;

      // otherwise, normal alphabetical sorting
      return (a.name > b.name) ? 1 : -1;
    });
    
console.log(obj.names);    

或者,您可以执行较长的“单线”操作:
filter返回一个新数组,其中删除了obj.firstobj.second
sort然后按照通常的规则对新数组进行排序。
concat返回一个新数组,该数组将已排序的数组追加到[obj.first, obj.second],即您的“起始”数组。

let obj = {
  first: 'Zangief',
  second: 'Cammy',

  names: [
    {name: 'Dee Jay'},
    {name: 'Zangief'},
    {name: 'Dhalsim'},
    {name: 'Chun-Li'},
    {name: 'Blanka'},
    {name: 'Cammy'}
  ]
};

let sorted = [{name: obj.first}, {name: obj.second}]
  .concat(obj.names.filter(item => (
    ((item.name !== obj.first) && 
     (item.name !== obj.second))
  )).sort((a, b) => (a.name > b.name)
      ? 1 
      : ((b.name > a.name) ? -1 : 0)
  ));

console.log(sorted);

// simplified data structure
const first = 'Zangief';
const second= 'Cammy';

const names = [
    'Dee Jay',
    'Zangief',
    'Dhalsim',
    'Chun-Li',
    'Blanka',
    'Cammy'
];

// filter/concat (version 2) does not alter original names array.    
let sorted = [first, second]
  .concat(names.filter(name => (
    !((name == first) || (name == second))
  )).sort());
  
console.log("new sorted array, (version 2) via filter/concat: \n", sorted);

// orig array untouched
console.log("original names array (untouched): \n", names);

// custom sort, (version 1) alters the original names array.
names.sort((a,b) => {
      // 'Zangief' gets moved to the front.
      if (a === first) return -1;
      if (b === first || b === second) return 1;

      // Othwerwise 'Cammy' moves forward.
      if (a === second) return -1;
//      if (b === second) return 1;

      // all other strings: normal alphabetical sorting
      return (a, b) => (a > b) ? 1 : ((b > a) ? -1 : 0)
    });
    
console.log("names array, altered, after (version 1) sorting", names);