Javascript - sort array based on another array

后端 未结 22 1470
鱼传尺愫
鱼传尺愫 2020-11-22 03:45

Is it possible to sort and rearrange an array that looks like this:

itemsArray = [ 
    [\'Anne\', \'a\'],
    [\'Bob\', \'b\'],
    [\'Henry\', \'b\'],
             


        
相关标签:
22条回答
  • 2020-11-22 04:15

    Why not something like

    //array1: array of elements to be sorted
    //array2: array with the indexes
    
    array1 = array2.map((object, i) => array1[object]);
    

    The map function may not be available on all versions of Javascript

    0 讨论(0)
  • 2020-11-22 04:16

    One Line answer.

    itemsArray.sort(function(a, b){  
      return sortingArr.indexOf(a) - sortingArr.indexOf(b);
    });
    
    0 讨论(0)
  • 2020-11-22 04:16

    Case 1: Original Question (No Libraries)

    Plenty of other answers that work. :)

    Case 2: Original Question (Lodash.js or Underscore.js)

    var groups = _.groupBy(itemArray, 1);
    var result = _.map(sortArray, function (i) { return groups[i].shift(); });
    

    Case 3: Sort Array1 as if it were Array2

    I'm guessing that most people came here looking for an equivalent to PHP's array_multisort (I did) so I thought I'd post that answer as well. There are a couple options:

    1. There's an existing JS implementation of array_multisort(). Thanks to @Adnan for pointing it out in the comments. It is pretty large, though.

    2. Write your own. (JSFiddle demo)

    function refSort (targetData, refData) {
      // Create an array of indices [0, 1, 2, ...N].
      var indices = Object.keys(refData);
    
      // Sort array of indices according to the reference data.
      indices.sort(function(indexA, indexB) {
        if (refData[indexA] < refData[indexB]) {
          return -1;
        } else if (refData[indexA] > refData[indexB]) {
          return 1;
        }
        return 0;
      });
    
      // Map array of indices to corresponding values of the target array.
      return indices.map(function(index) {
        return targetData[index];
      });
    }
    

    3. Lodash.js or Underscore.js (both popular, smaller libraries that focus on performance) offer helper functions that allow you to do this:

        var result = _.chain(sortArray)
          .pairs()
          .sortBy(1)
          .map(function (i) { return itemArray[i[0]]; })
          .value();
    

    ...Which will (1) group the sortArray into [index, value] pairs, (2) sort them by the value (you can also provide a callback here), (3) replace each of the pairs with the item from the itemArray at the index the pair originated from.

    0 讨论(0)
  • 2020-11-22 04:18

    function sortFunc(a, b) {
      var sortingArr = ["A", "B", "C"];
      return sortingArr.indexOf(a.type) - sortingArr.indexOf(b.type);
    }
    
    const itemsArray = [
      {
        type: "A",
      },
      {
        type: "C",
      },
      {
        type: "B",
      },
    ];
    console.log(itemsArray);
    itemsArray.sort(sortFunc);
    console.log(itemsArray);

    0 讨论(0)
  • 2020-11-22 04:19

    Something like:

    items = [ 
        ['Anne', 'a'],
        ['Bob', 'b'],
        ['Henry', 'b'],
        ['Andrew', 'd'],
        ['Jason', 'c'],
        ['Thomas', 'b']
    ]
    
    sorting = [ 'b', 'c', 'b', 'b', 'c', 'd' ];
    result = []
    
    sorting.forEach(function(key) {
        var found = false;
        items = items.filter(function(item) {
            if(!found && item[1] == key) {
                result.push(item);
                found = true;
                return false;
            } else 
                return true;
        })
    })
    
    result.forEach(function(item) {
        document.writeln(item[0]) /// Bob Jason Henry Thomas Andrew
    })
    

    Here's a shorter code, but it destroys the sorting array:

    result = items.map(function(item) {
        var n = sorting.indexOf(item[1]);
        sorting[n] = '';
        return [n, item]
    }).sort().map(function(j) { return j[1] })
    
    0 讨论(0)
  • 2020-11-22 04:20

    I would use an intermediary object (itemsMap), thus avoiding quadratic complexity:

    function createItemsMap(itemsArray) { // {"a": ["Anne"], "b": ["Bob", "Henry"], …}
      var itemsMap = {};
      for (var i = 0, item; (item = itemsArray[i]); ++i) {
        (itemsMap[item[1]] || (itemsMap[item[1]] = [])).push(item[0]);
      }
      return itemsMap;
    }
    
    function sortByKeys(itemsArray, sortingArr) {
      var itemsMap = createItemsMap(itemsArray), result = [];
      for (var i = 0; i < sortingArr.length; ++i) {
        var key = sortingArr[i];
        result.push([itemsMap[key].shift(), key]);
      }
      return result;
    }
    

    See http://jsfiddle.net/eUskE/

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