简体   繁体   English

Javascript Lodash 按外部数组和内部属性排序

[英]Javascript Lodash sort by external array and internal property

I have an array of people that I need to sort by a defined external array (order) and then by age.我有一组人,我需要按定义的外部数组(顺序)然后按年龄进行排序。 I am using lodash sortBy我正在使用 lodash sortBy

const _  = require('lodash');
const arr = [
  { name: "Mandy", age: "34" },
  { name: "Shelly", age: "32" },
  { name: "Kyle", age: "12" },
  { name: "Kyle", age: "60" },
  { name: "Mandy", age: "32" },
  { name: "Mandy", age: "99" },
  { name: "Shelly", age: "30" },
  { name: "John", age: "3" },
  { name: "John", age: "1" },
  { name: "John", age: "6" },
  { name: "Mandy", age: "3" }
];

let order = ["Shelly", "John", "Mandy", "Kyle"];

let sortedArrByOrder = _.sortBy(arr, [person => order.indexOf(person.name), 'age'], ['asc', 'desc']);

console.log(sortedArrByOrder);

But the age is not sorted in desc order.但是年龄不是按降序排列的。 Is there a way to make it work?有没有办法让它工作?

The _.sortBy() doesn't except order (asc / desc), use _.orderBy() instead: _.sortBy()除了 order (asc / desc),使用_.orderBy()代替:

 const arr = [{ name: "Mandy", age: "34" },{ name: "Shelly", age: "32" },{ name: "Kyle", age: "12" },{ name: "Kyle", age: "60" },{ name: "Mandy", age: "32" },{ name: "Mandy", age: "99" },{ name: "Shelly", age: "30" },{ name: "John", age: "3" },{ name: "John", age: "1" },{ name: "John", age: "6" },{ name: "Mandy", age: "3" }]; const order = ["Shelly", "John", "Mandy", "Kyle"]; const sortedArrByOrder = _.orderBy(arr, [person => order.indexOf(person.name), 'age'], ['asc', 'desc']); console.log(sortedArrByOrder);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

In addition, using Array.indexOf() (O(n)) inside a sort operation (O(nLogn) for array with more than 10 items), might hurt the performance.此外,在排序操作中使用Array.indexOf() (O(n)) (O(nLogn) 用于超过 10 个项目的数组),可能会损害性能。 A better way would be to convert the order array to a data structure with O(1) retrieval like an Map or plain object, and store the original index from the array.更好的方法是将order数组转换为具有 O(1) 检索的数据结构,如 Map 或普通 object,并存储数组中的原始索引。 Now you can get the original index directly:现在可以直接获取原始索引:

 const arr = [{ name: "Mandy", age: "34" },{ name: "Shelly", age: "32" },{ name: "Kyle", age: "12" },{ name: "Kyle", age: "60" },{ name: "Mandy", age: "32" },{ name: "Mandy", age: "99" },{ name: "Shelly", age: "30" },{ name: "John", age: "3" },{ name: "John", age: "1" },{ name: "John", age: "6" },{ name: "Mandy", age: "3" }]; const order = new Map(["Shelly", "John", "Mandy", "Kyle"].map((s, i) => [s, i])) const sortedArrByOrder = _.orderBy(arr, [person => order.get(person.name), 'age'], ['asc', 'desc']); console.log(sortedArrByOrder);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

You could take a callback and return the negative age and omit the array for the order.您可以进行回调并返回负年龄并省略订单数组。

 const arr = [{ name: "Mandy", age: "34" }, { name: "Shelly", age: "32" }, { name: "Kyle", age: "12" }, { name: "Kyle", age: "60" }, { name: "Mandy", age: "32" }, { name: "Mandy", age: "99" }, { name: "Shelly", age: "30" }, { name: "John", age: "3" }, { name: "John", age: "1" }, { name: "John", age: "6" }, { name: "Mandy", age: "3" }], order = ["Shelly", "John", "Mandy", "Kyle"], sortedArrByOrder = _.sortBy(arr, [ ({ name }) => order.indexOf(name), ({ age }) => -age ]); console.log(sortedArrByOrder);
 .as-console-wrapper { max-height: 100%;important: top; 0; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

You can do this with sort method in plain javascript with ||您可以使用带有||的普通 javascript 中的sort方法执行此操作operator.操作员。 So you first sort by order and then by age .因此,您首先按顺序排序,然后按age排序。

 const arr = [{ name: "Mandy", age: "34" },{ name: "Shelly", age: "32" },{ name: "Kyle", age: "12" },{ name: "Kyle", age: "60" },{ name: "Mandy", age: "32" },{ name: "Mandy", age: "99" },{ name: "Shelly", age: "30" },{ name: "John", age: "3" },{ name: "John", age: "1" },{ name: "John", age: "6" },{ name: "Mandy", age: "3" }]; const order = ["Shelly", "John", "Mandy", "Kyle"]; arr.sort((a, b) => order.indexOf(a.name) - order.indexOf(b.name) || b.age - a.age) console.log(arr)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM