最好使用Lodash按查找表对值排序

时间:2018-12-12 17:37:45

标签: javascript arrays sorting lodash

我的数据如下:

var list = [
{ name:'Charlie', age:3},
{ name:'Dog', age:1 },
{ name:'Baker', age:7},
{ name:'Abel', age:9 },
{ name:'Jim', age:5 }
];

我想添加自定义订单,例如不是按数值或字母顺序。我猜我需要创建一个查询表来完成我的独特订单/排名,如下所示。

var rank = [
0: {'Abel'},
1: {'Baker'},
2: {'Jim'},
3: {'Charlie'},
4: {'Dog'}]

const name = _.sortBy(names, list=>{return list.name});

我的name应该= Abel,因为我只对谁是最高的感兴趣。如果Abel不存在,那么name将带回Baker等...

我可能需要使用Lodash sortBy,但是可以使用其他干净的解决方案。

2 个答案:

答案 0 :(得分:1)

您可以使用具有所需值的哈希表进行排序。

对于未知名称,您可以添加默认值,并将这些项目移动到顶部(小于1)或底部(Infinity)。

排序值应不同于零,因为默认的伪性质为零,否则默认值将不起作用。

var list = [{ name: 'Charlie', age:3 }, { name: 'Dog', age: 1 }, { name: 'Baker', age: 7 }, { name: 'Abel', age: 9 }, { name: 'Jim', age: 5 }],
    rank = { Abel: 1, Baker: 2, Jim: 3, Charlie: 4, Dog: 5 },
    ordered = _.sortBy(list, ({ name }) => rank[name]);

console.log(ordered);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

答案 1 :(得分:0)

一种实现方法是,将排名存储在数组中,然后使用它来获取列表项的排序位置。这样效果很好,因为它可以确保您不会使用某个奇怪的位置,但是必须将每个条目从listrank

var list = [
  { name:'Charlie', age:3 },
  { name:'Dog', age:1 },
  { name:'Baker', age:7 },
  { name:'Abel', age:9 },
  { name:'Jim', age:5 }
];

var rank = [
  'Abel',
  'Baker',
  'Jim',
  'Charlie',
  'Dog'
];


var sorted = _.sortBy(list, item => rank.indexOf(item.name));

console.log(sorted);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>

这里的另一种选择是对数组进行排序,而是根据排名顺序生成新的数组:

var list = [
  { name:'Charlie', age:3 },
  { name:'Dog', age:1 },
  { name:'Baker', age:7 },
  { name:'Abel', age:9 },
  { name:'Jim', age:5 }
];

var rank = [
  'Abel',
  'Baker',
  'Jim',
  'Charlie',
  'Dog'
];


var sorted = _.map(rank, rankItem => _.find(list, item => item.name === rankItem));

console.log(sorted);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>

您还可以使用排名查询表。这将更加有效,因为您不需要每次都遍历数组来获取排名-所有这些都是预先计算的。但是除此之外,它与第一个解决方案几乎相同:

var list = [
  { name:'Charlie', age:3},
  { name:'Dog', age:1 },
  { name:'Baker', age:7},
  { name:'Abel', age:9 },
  { name:'Jim', age:5 }
];

var rank = {
  'Abel': 1,
  'Baker': 2,
  'Jim': 3,
  'Charlie': 4,
  'Dog': 5
};

var sorted = _.sortBy(list, item => rank[item.name]);

console.log(sorted);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>

应该注意的是,您也可以使用普通的JavaScript来做到这一点,尽管它有些冗长:

var list = [
  { name:'Charlie', age:3 },
  { name:'Dog', age:1 },
  { name:'Baker', age:7 },
  { name:'Abel', age:9 },
  { name:'Jim', age:5 }
];

var rank = [
  'Abel',
  'Baker',
  'Jim',
  'Charlie',
  'Dog'
];

//in-place sorting
list.sort((a, b) => rank.indexOf(a.name) - rank.indexOf(b.name));
console.log(list);

var list = [
  { name:'Charlie', age:3},
  { name:'Dog', age:1 },
  { name:'Baker', age:7},
  { name:'Abel', age:9 },
  { name:'Jim', age:5 }
];

var rank = {
  'Abel': 1,
  'Baker': 2,
  'Jim': 3,
  'Charlie': 4,
  'Dog': 5
};

//in-place sorting
list.sort((a, b) => rank[a.name] - rank[b.name]);
console.log(list);