How to get first n elements of an object using lodash?

后端 未结 3 803
孤街浪徒
孤街浪徒 2021-02-19 21:26

I want to get the first n key/value pairs from an object (not an array) using lodash. I found this answer for underscore, which says to use use first (doesn\'

相关标签:
3条回答
  • 2021-02-19 22:01

    You cannot take the first N elements of an object without writing custom code. This is because there is no ordering of the elements in objects, so if there were a library function for it, it would never be guaranteed to give you the elements you expect. Given an object like

    var obj = {  b: 3, y: 2, a: 1 };
    

    it is not clear what the "first 2" refers to - do you want a and b because that is the alphabetic order? If so are they in that order or not? If not, do you want b and y because they appear first? Perhaps you want a and y because of their values being the lowest?

    There is no guarantee for what you will get aside from not getting duplicates, so all of those combinations are valid. Furthermore, you can get them in any order y and a is equally valid output You may prefer one or another but it doesn't make it correct in general.

    There are ways around this and but you have to accept that you need to deal with the non-order.

    Pure JavaScript solution.

    function firstN(obj, n) {
      return Object.keys(obj) //get the keys out
        .sort() //this will ensure consistent ordering of what you will get back. If you want something in non-aphabetical order, you will need to supply a custom sorting function
        .slice(0, n) //get the first N
        .reduce(function(memo, current) { //generate a new object out of them
          memo[current] = obj[current]
          return memo;
        }, {})
    }
    var obj = { b: 2, y: 25, a: 1 }
    
    console.log( firstN(obj, 2) );

    This is using Object.keys, Array.prototype.sort, and Array.prototype.reduce

    The same can be achieved with lodash but not vastly more concise than this - it would involve calling similar functionality. It can be done like this, for example:

    function firstN(obj, n) {
      return _.chain(obj)
        .keys()
        .sort()
        .take(n)
        .reduce(function(memo, current) {
          memo[current] = obj[current];
          return memo;
        }, {})
        .value();
    }
    
    var obj = { b: 2, y: 25, a: 1 }
          
    console.log( firstN(obj, 2) );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

    As you can see, it's pretty much the same as before. There can be variations on the syntax and the exact means of how you do this task, but the major points should still be there - you need to sort for consistency and then you can get any number of items.

    0 讨论(0)
  • 2021-02-19 22:10

    If you look at the loadash documentation for first. It only takes in an array as its argument, and this is probably not the API to use.

    See: https://lodash.com/docs/3.10.1#first


    Here is 1 method you can solve it using standard Javascript API.

    The catch here is that you can use the Object.keys(...)[index] API to retrieve the element's key based on their position.

    Then all you need to do is just loop n number of times and using the derived key push it into another object.

    var firstN = 2;
    var o={a:7, b:8, c:9};
    var result = {};
    
    for (var index=0; index < firstN; index++) {
      var key = Object.keys(o)[index];
      result[key] = o[key];
    }
    
    console.log(result);

    0 讨论(0)
  • 2021-02-19 22:14

    There is no straight-forward solution. Inspired by previous answers and comments, and reading a couple of articles about non-guaranteed properties order, I created a solution where I sort the keys first.

    Sorting the keys

    Here is a usable one-line approach with sorted keys (and therefore guaranteed order).

    Chaining

    _.chain(object).toPairs().sortBy(0).take(2).fromPairs().value()
    

    Without chaining

    _.fromPairs(_.take(_.sortBy(_.toPairs(object), 0), 2)),
    

    Details on sorting

    The sortBy(0) sorts our collection by keys (index 0). The original object is at first converted by toPairs() to an array of pairs (each pair is an array [key, value]) and then sorted by the first values of these pairs (the key has index 0 in the pair).


    Important: As mentioned in previous answers and comments, the order of properties cannot be guaranteed, even in the latest ES versions. See this updated SO answer. Therefore I am sorting the keys.

    0 讨论(0)
提交回复
热议问题