Javascript - 基於另一個數組排序數組



6 Answers

一線答案。

itemsArray.sort(function(a, b){  
  return sortingArr.indexOf(a) - sortingArr.indexOf(b);
});
javascript

是否可以對如下所示的數組進行排序和重新排列:

itemsArray = [ 
    ['Anne', 'a'],
    ['Bob', 'b'],
    ['Henry', 'b'],
    ['Andrew', 'd'],
    ['Jason', 'c'],
    ['Thomas', 'b']
]

匹配此數組的排列:

sortingArr = [ 'b', 'c', 'b', 'b', 'a', 'd' ]

不幸的是,我沒有任何ID可以跟踪。 我需要優先使items-array與sortedArr匹配盡可能接近。

更新:

這是我正在尋找的輸出:

itemsArray = [    
    ['Bob', 'b'],
    ['Jason', 'c'],
    ['Henry', 'b'],
    ['Thomas', 'b']
    ['Anne', 'a'],
    ['Andrew', 'd'],
]

知道如何做到這一點?




案例1:原始問題(無庫)

還有很多其他有用的答案。 :)

案例2:原始問題(Lodash.js或Underscore.js)

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

情況3:將Array1排序為Array2

我猜大多數人來到這裡尋找相當於PHP的array_multisort(我做過),所以我想我也會發布這個答案。 有幾種選擇:

1.有一個array_multisort()的現有JS實現 。 感謝@Adnan在評論中指出它。 但它非常大。

2.自己寫。 ( JSFiddle演示

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.jsUnderscore.js (兩者都是專注於性能的流行的小型庫)提供了幫助您執行此操作的輔助函數:

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

...其中(1)將sortArray分組為[index, value]對,(2)按值排序(這裡也可以提供回調),(3)將每個對替換為來自itemArray位於該對的索引處。




我會使用一個中間對象( itemsMap ),從而避免二次復雜性:

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;
}

http://jsfiddle.net/eUskE/




我必須為從API接收的JSON有效負載執行此操作,但它不是我想要的順序。

數組作為引用數組,你希望第二個數組按以下順序排序:

var columns = [
    {last_name: "last_name"},
    {first_name: "first_name"},
    {book_description: "book_description"},
    {book_id: "book_id"},
    {book_number: "book_number"},
    {due_date: "due_date"},
    {loaned_out: "loaned_out"}
];

我把它們當作對象,因為它們最終會有其他屬性。

創建數組:

 var referenceArray= [];
 for (var key in columns) {
     for (var j in columns[key]){
         referenceArray.push(j);
     }
  }

與數據庫中的結果集一起使用。 我不知道它有多高效,但由於我使用的列數很少,它工作得很好。

result.forEach((element, index, array) => {                            
    var tr = document.createElement('tr');
    for (var i = 0; i < referenceArray.length - 1; i++) {
        var td = document.createElement('td');
        td.innerHTML = element[referenceArray[i]];
        tr.appendChild(td);

    }
    tableBody.appendChild(tr);
}); 



使用jQuery中的$ .inArray()方法。 然後你可以做這樣的事情

var sortingArr = [ 'b', 'c', 'b', 'b', 'c', 'd' ];
var newSortedArray = new Array();

for(var i=sortingArr.length; i--;) {
 var foundIn = $.inArray(sortingArr[i], itemsArray);
 newSortedArray.push(itemsArray[foundIn]);
}



這應該有效:

var i,search, itemsArraySorted = [];
while(sortingArr.length) {
    search = sortingArr.shift();
    for(i = 0; i<itemsArray.length; i++) {
        if(itemsArray[i][1] == search) {
            itemsArraySorted.push(itemsArray[i]);
            break;
        }
    } 
}

itemsArray = itemsArraySorted;



Related


Tags

javascript