最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Using lodash is it possible to sort an array of objects using several parameters - Stack Overflow

programmeradmin0浏览0评论

Using lodash I’d like to be able to sort an array of objects like below (but much larger) by several keys, some of which are nested in arrays: The precedence would be:

  1. Ine to a given year (ie provide (say) 2012 and ine would be used for that year for all elements)
  2. displayInGraph (being true)
  3. pinnedRow (being true)

I’d also like to be able to reverse the above.

I've looked in the lodash documentation but cannot see the solution to my question:

[{
    displayInGraph: true,
    pinnedRow: true,
    dateRange: [{
      year: 2010,
      ine: 20000
    }, {
      year: 2011,
      ine: 30000
    }, {
      year: 2012,
      ine: 40000
    }, {
      year: 2013,
      ine: 44000
    }]
  },
  {
    displayInGraph: true,
    pinnedRow: false,
    dateRange: [{
      year: 2010,
      ine: 20000
    }, {
      year: 2011,
      ine: 32500
    }, {
      year: 2012,
      ine: 50000
    }, {
      year: 2013,
      ine: 45200
    }]
  },

  {
    displayInGraph: true,
    pinnedRow: false,
    dateRange: [{
      year: 2010,
      ine: 20400
    }, {
      year: 2011,
      ine: 38000
    }, {
      year: 2012,
      ine: 30000
    }, {
      year: 2013,
      ine: 45000
    }]
  },

  {
    displayInGraph: true,
    pinnedRow: true,
    dateRange: [{
      year: 2010,
      ine: 21030
    }, {
      year: 2011,
      ine: 39000
    }, {
      year: 2012,
      ine: 44000
    }, {
      year: 2013,
      ine: 45400
    }]
  }
]

Using lodash I’d like to be able to sort an array of objects like below (but much larger) by several keys, some of which are nested in arrays: The precedence would be:

  1. Ine to a given year (ie provide (say) 2012 and ine would be used for that year for all elements)
  2. displayInGraph (being true)
  3. pinnedRow (being true)

I’d also like to be able to reverse the above.

I've looked in the lodash documentation but cannot see the solution to my question:

[{
    displayInGraph: true,
    pinnedRow: true,
    dateRange: [{
      year: 2010,
      ine: 20000
    }, {
      year: 2011,
      ine: 30000
    }, {
      year: 2012,
      ine: 40000
    }, {
      year: 2013,
      ine: 44000
    }]
  },
  {
    displayInGraph: true,
    pinnedRow: false,
    dateRange: [{
      year: 2010,
      ine: 20000
    }, {
      year: 2011,
      ine: 32500
    }, {
      year: 2012,
      ine: 50000
    }, {
      year: 2013,
      ine: 45200
    }]
  },

  {
    displayInGraph: true,
    pinnedRow: false,
    dateRange: [{
      year: 2010,
      ine: 20400
    }, {
      year: 2011,
      ine: 38000
    }, {
      year: 2012,
      ine: 30000
    }, {
      year: 2013,
      ine: 45000
    }]
  },

  {
    displayInGraph: true,
    pinnedRow: true,
    dateRange: [{
      year: 2010,
      ine: 21030
    }, {
      year: 2011,
      ine: 39000
    }, {
      year: 2012,
      ine: 44000
    }, {
      year: 2013,
      ine: 45400
    }]
  }
]

Thanks in advance for solutions

Share Improve this question edited Jan 24, 2018 at 0:26 user2190690 asked Jan 24, 2018 at 0:03 user2190690user2190690 2,0444 gold badges26 silver badges32 bronze badges 2
  • 1 fyi, your snippet is not valid javascript, (there are no keys for your year/ine arrays). – CRice Commented Jan 24, 2018 at 0:10
  • @CRice, thank you - edited... – user2190690 Commented Jan 24, 2018 at 0:26
Add a ment  | 

3 Answers 3

Reset to default 6

You can use lodash to sort by multiple properties within an object by having the iterated function return an array of the properties that you want to sort. This example will sort by property a, then property b, then property sortkey.

var input = [
 { a: 4, b: 5, data: 9, sortkey: "blue" },
 { a: 3, b: 9, data: 27, sortkey: "red" },
 { a: 3, b: 9, data: 4, sortkey: "green" },
 { a: 3, b: 3, data: 19, sortkey: "purple" },
 { a: 4, b: 3, data: 6, sortkey: "white" },
 { a: 5, b: 0, data: 0, sortkey: "orange" }
];

var output = _.sortBy(input, function(o) {
  return [o.a, o.b, o.sortkey];
});

See fiddle: https://jsfiddle/mikeular/qog6h9ez/3/ .

You could then reverse the sort behavior by updating the array. For example, if you wanted a ascending, b descending, and sortkey ascending, you can do something like:

var output = _.sortBy(input, function(o) {
  return [o.a, -1 * o.b, o.sortkey];
});

(I prefer -1 * o.b over -o.b to elevate the visibility of the reversal).

It would be a fun exercise to see how it performs vs the somewhat cleaner:

var output = _.sortBy(input, ['a', 'b', 'sortkey']);

...if performance is relevant to you.

Lodash has a _.sortBy method which accepts as it's second argument either a string (as a path to the sort property), or a function (which returns the sort property), or an array thereof. So you can sort on multiple parameters by using an array of sort functions:

const myArray = [{
    displayInGraph: true,
    pinnedRow: true,
    dateRange: [{
      year: 2010,
      ine: 20000
    }, {
      year: 2011,
      ine: 30000
    }, {
      year: 2012,
      ine: 40000
    }, {
      year: 2013,
      ine: 44000
    }]
  },
  {
    displayInGraph: true,
    pinnedRow: false,
    dateRange: [{
      year: 2010,
      ine: 20000
    }, {
      year: 2011,
      ine: 32500
    }, {
      year: 2012,
      ine: 50000
    }, {
      year: 2013,
      ine: 45200
    }]
  },

  {
    displayInGraph: true,
    pinnedRow: false,
    dateRange: [{
      year: 2010,
      ine: 20400
    }, {
      year: 2011,
      ine: 38000
    }, {
      year: 2012,
      ine: 30000
    }, {
      year: 2013,
      ine: 45000
    }]
  },

  {
    displayInGraph: true,
    pinnedRow: true,
    dateRange: [{
      year: 2010,
      ine: 21030
    }, {
      year: 2011,
      ine: 39000
    }, {
      year: 2012,
      ine: 44000
    }, {
      year: 2013,
      ine: 45400
    }]
  }
]

console.log(_.sortBy(myArray, [
    item => (item.dateRange.find(range => range.year === 2012) || {ine: 0}).ine,
    item => item.displayInGraph,
    item => item.pinnedRow,
]));
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.17.4/lodash.js"></script>

Finally, you can reverse the result by using the javascript built in array .reverse method.

Have you tried with sortBy? It can receive a list of functions used to perform each step of the sort.

For example you can:

const year = 2012;
const getIne = (obj) => _.find(obj.dateRange, {ine: year});
_.sortBy(users, [getIne, 'displayInGraph', 'pinnedRow']);
发布评论

评论列表(0)

  1. 暂无评论