how to sort an array of objects using a related property from objects in second array

后端 未结 5 826
有刺的猬
有刺的猬 2021-01-26 09:06

There are many questions regarding sorting with JavaScript but I didn\'t find anything that addresses this case so I don\'t believe this is a duplicate.

I\'m getting dat

相关标签:
5条回答
  • 2021-01-26 09:38

    Here's my solution:

    var items = [
        { id: 1, name: 'bill' },
        { id: 2, name: 'sam' },
        { id: 3, name: 'mary' },
        { id: 4, name: 'jane' }
    ];
    
    var order = [
        { id: 1, sortindex: 4 },
        { id: 2, sortindex: 2 },
        { id: 3, sortindex: 1 },
        { id: 4, sortindex: 3 }
    ];
    
    _(items)
        .indexBy('id')
        .at(_.pluck(_.sortBy(order, 'sortindex'), 'id'))
        .pluck('name')
        .value();
    // → [ 'mary', 'sam', 'jane', 'bill' ]
    

    Here's what's going on:

    • The indexBy() function transforms items into an object, where the id values are the keys.
    • The at() function gets values from the object, in order, of the passed in keys.
    • The sortBy() function sorts order by the sortindex key.
    • The pluck() function gets the sorted id array.
    0 讨论(0)
  • 2021-01-26 09:45

    It's straightforward with lodash. The sortBy function will move the items to the sortindex position, so we just need to use find to get the corresponding object, and return its sortindex property for sortBy to use.

    var items = [{id:1, name:'bill'}, {id:2, name:'sam'}, {id:3, name: 'mary'}, {id:4, name:'jane'}];
    var order = [{id:1, sortindex:4}, {id:2, sortindex:2}, {id:3, sortindex: 1}, {id:4, sortindex:3}];
    
    var sorted = _.sortBy(items, function(item) {
      // sorts by the value returned here
      return _.find(order, function(ordItem) {
        // find the object where the id's match
        return item.id === ordItem.id;
      }).sortindex; // that object's sortindex property is returned
    });
    
    document.body.textContent = JSON.stringify(sorted);
    <script src="https://rawgit.com/lodash/lodash/3.0.1/lodash.min.js"></script>

    0 讨论(0)
  • 2021-01-26 09:50

    Here's my solution. If you know that both arrays will match in length and location of id's, then this is a concise solution:

    _.chain(items)
     .merge(order)
     .sortBy('sortindex')
     .map(_.partialRight(_.omit, 'sortindex'))
     .value()
    

    Otherwise, if they aren't guaranteed to be sorted, then the items can be resolved with a map/find/merge.

    _.chain(items)
     .map(function(item) { 
        return _.merge(item, _.find(order, {'id': item.id})); 
     })
     .sortBy('sortindex')
     .map(_.partialRight(_.omit, 'sortindex'))
     .value()
    
    0 讨论(0)
  • 2021-01-26 09:55

    If you store your order as a map, it's rather straight forward with vanilla Javascript.

    var items = [{id:1, name:'bill'}, {id:2, name:'sam'}, {id:3, name: 'mary'}, {id:4, name:'jane'}];
    var order = {1:4, 2:2, 3:1, 4:3};
    items.sort(function (a, b) {
        return (order[a.id] > order[b.id]) - (order[a.id] < order[b.id]);
    });
    

    Or if you insist on your original data, assuming it's already sorted as you show it to be:

    var items = [{id:1, name:'bill'}, {id:2, name:'sam'}, {id:3, name: 'mary'}, {id:4, name:'jane'}];
    var order = [{id:1, sortindex:4}, {id:2, sortindex:2}, {id:3, sortindex: 1}, {id:4, sortindex:3}];
    
    items.sort(function (a, b) {
        var ai = order[a.id - 1].sortindex;
        var bi = order[b.id - 1].sortindex;
        return (ai > bi) - (ai < bi);
    });
    

    If you can't assume the data is sorted, see this question, for example on how to create a map from your data.

    0 讨论(0)
  • 2021-01-26 09:57

    See in demo: http://jsbin.com/qaquzi/1/edit?js,console

    //items array 
    var items = [{id:1, name:'bill'}, {id:2, name:'sam'}, {id:3, name: 'mary'}, {id:4, name:'jane'}]
    
    //sort order array
    var order = [{id:1, sortindex:4}, {id:2, sortindex:2}, {id:3, sortindex: 1}, {id:4, sortindex:3}]
    
    
    var sortedOrder = _.sortBy(order, 'sortindex');
    
    var bb = _.map(sortedOrder, function (i) {
        return i.id;
    })
    
    var sorted = [];
    
    for (var i = 0, ii = bb.length; i < ii; i++) {
        for (var m = 0, mm = items.length; m < mm; m++) {
            var a = items[m];
            if (a.id == bb[i]) {
                sorted.push(items[m]);
            }
        }
    }
    
    console.log(sorted);
    
    0 讨论(0)
提交回复
热议问题