繁体   English   中英

Javascript - 根据另一个数组对数组进行排序

[英]Javascript - sort array based on another array

是否可以对如下所示的数组进行排序和重新排列:

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

匹配这个数组的排列:

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

不幸的是,我没有任何 ID 可以跟踪。 我需要优先考虑项目数组以尽可能接近地匹配 sortingArr。

更新:

这是我要找的 output:

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

知道如何做到这一点吗?

单行答案。

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

甚至更短:

itemsArray.sort((a, b) => sortingArr.indexOf(a) - sortingArr.indexOf(b));

就像是:

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

这是一个较短的代码,但它破坏了sorting数组:

result = items.map(function(item) {
    var n = sorting.indexOf(item[1]);
    sorting[n] = '';
    return [n, item]
}).sort().map(function(j) { return j[1] })

如果您使用原生数组排序功能,您可以传入自定义比较器以在对数组进行排序时使用。 如果第一个值小于第二个,比较器应该返回一个负数,如果它们相等则返回零,如果第一个值更大,则比较器应该返回一个正数。

因此,如果我理解您正确给出的示例,您可以执行以下操作:

function sortFunc(a, b) {
  var sortingArr = [ 'b', 'c', 'b', 'b', 'c', 'd' ];
  return sortingArr.indexOf(a[1]) - sortingArr.indexOf(b[1]);
}

itemsArray.sort(sortFunc);

案例 1:原始问题(无库)<\/h2>

许多其他有效的答案。 :)

案例 2:原始问题(Lodash.js 或 Underscore.js)<\/h2>
案例 3:像 Array2 一样对 Array1 进行排序<\/h2>

我猜大多数人来这里是为了寻找与 PHP 的 array_multisort 等效的东西(我做过),所以我想我也会发布这个答案。 有几个选项:

1. array_multisort() 有一个现有的 JS 实现<\/a>。 感谢@Adnan 在评论中指出。 不过,它相当大。

2. 自己写。 JSFiddle 演示<\/a>)

 3. Lodash.js<\/a>或Underscore.js<\/a> (都是流行的,专注于性能的小型库)提供帮助函数,让您可以这样做:

 ...这将(1)将 sortArray 分组为[index, value]<\/code>对,(2)按值对它们进行排序(您也可以在此处提供回调),(3)用itemArray 位于该对源自的索引处。

"

这可能为时已晚,但您也可以使用 ES6 风格的以下代码的一些修改版本。 此代码适用于以下数组:

var arrayToBeSorted = [1,2,3,4,5];
var arrayWithReferenceOrder = [3,5,8,9];

为什么不喜欢

//array1: array of elements to be sorted
//array2: array with the indexes

array1 = array2.map((object, i) => array1[object]);

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

我会使用中间对象( 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/

var sortedArray = [];
for(var i=0; i < sortingArr.length; i++) {
    var found = false;
    for(var j=0; j < itemsArray.length && !found; j++) {
        if(itemsArray[j][1] == sortingArr[i]) {
            sortedArray.push(itemsArray[j]);
            itemsArray.splice(j,1);
            found = true;
        }
    }
}

ES6

const arrayMap = itemsArray.reduce(
  (accumulator, currentValue) => ({
    ...accumulator,
    [currentValue[1]]: currentValue,
  }),
  {}
);
const result = sortingArr.map(key => arrayMap[key]);

如果您到这里需要对一组对象执行此操作,这里是对@Durgpal Singh 的精彩回答的改编:

const itemsArray = [
  { name: 'Anne', id: 'a' },
  { name: 'Bob', id: 'b' },
  { name: 'Henry', id: 'b' },
  { name: 'Andrew', id: 'd' },
  { name: 'Jason', id: 'c' },
  { name: 'Thomas', id: 'b' }
]

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

Object.keys(itemsArray).sort((a, b) => {
  return sortingArr.indexOf(itemsArray[a].id) - sortingArr.indexOf(itemsArray[b].id);
})
let a = ['A', 'B', 'C' ]

let b = [3, 2, 1]

let c = [1.0, 5.0, 2.0]

// these array can be sorted by sorting order of b

const zip = rows => rows[0].map((_, c) => rows.map(row => row[c]))

const sortBy = (a, b, c) => {
  const zippedArray = zip([a, b, c])
  const sortedZipped = zippedArray.sort((x, y) => x[1] - y[1])

  return zip(sortedZipped)
}

sortBy(a, b, c)

这就是我一直在寻找的东西,并且我根据另一个数组对数组数组进行排序:

它是 On^3 并且可能不是最佳实践(ES6)

它可能会帮助某人

"

我必须为从 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"}
];

为了获得一个新的有序数组,您可以使用一个Map并在一个数组中收集所有具有所需键的项目,并通过获取所需组的筛选元素来映射所需的有序键。

 var itemsArray = [['Anne', 'a'], ['Bob', 'b'], ['Henry', 'b'], ['Andrew', 'd'], ['Jason', 'c'], ['Thomas', 'b']], sortingArr = [ 'b', 'c', 'b', 'b', 'a', 'd' ], map = itemsArray.reduce((m, a) => m.set(a[1], (m.get(a[1]) || []).concat([a])), new Map), result = sortingArr.map(k => (map.get(k) || []).shift()); console.log(result);

let sortedOrder = [ 'b', 'c', 'b', 'b' ]
let itemsArray = [ 
    ['Anne', 'a'],
    ['Bob', 'b'],
    ['Henry', 'b'],
    ['Andrew', 'd'],
    ['Jason', 'c'],
    ['Thomas', 'b']
]
a.itemsArray(function (a, b) {
    let A = a[1]
    let B = b[1]

    if(A != undefined)
        A = A.toLowerCase()

    if(B != undefined)
        B = B.toLowerCase()

    let indA = sortedOrder.indexOf(A)
    let indB = sortedOrder.indexOf(B)

    if (indA == -1 )
        indA = sortedOrder.length-1
    if( indB == -1)
        indB = sortedOrder.length-1

    if (indA < indB ) {
        return -1;
    } else if (indA > indB) {
        return 1;
    }
    return 0;
})

我希望我能帮到别人,但是如果你试图通过第一个数组的键上的另一个数组对一个对象数组进行排序,例如,你想要对这个对象数组进行排序:

const foo = [
  {name: 'currency-question', key: 'value'},
  {name: 'phone-question', key: 'value'},
  {name: 'date-question', key: 'value'},
  {name: 'text-question', key: 'value'}
];        

通过这个数组:

const bar = ['text-question', 'phone-question', 'currency-question', 'date-question'];

你可以这样做:

foo.sort((a, b) => bar.indexOf(a.name) - bar.indexOf(b.name));
  const result = sortingArr.map((i) => {
    const pos = itemsArray.findIndex(j => j[1] === i);
    const item = itemsArray[pos];
    itemsArray.splice(pos, 1);
    return item;
  });

这应该有效:

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;

你可以试试这个方法。

const sortListByRanking = (rankingList, listToSort) => {
  let result = []

  for (let id of rankingList) {
    for (let item of listToSort) {
      if (item && item[1] === id) {
        result.push(item)
      }
    }
  }

  return result
}

使用数字排序Arr:

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

这似乎对我有用:

var outputArray=['10','6','8','10','4','6','2','10','4','0','2','10','0'];
var template=['0','2','4','6','8','10'];
var temp=[];

for(i=0;i<template.length;i++) {
  for(x=0;x<outputArray.length;x++){
    if(template[i] == outputArray[x]) temp.push(outputArray[x])
  };
}

outputArray = temp;
alert(outputArray)

使用 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 sortArray = ['a', 'b', 'c',  'd', 'e'];

var arrayToBeSort = ['z', 's', 'b',  'e', 'a'];

_.intersection(sortArray, arrayToBeSort) 

=> ['a', 'b', 'e']

如果 'z 和 's' 超出第一个数组的范围,则将其附加到结果的末尾

this.arrToBeSorted =  this.arrToBeSorted.sort(function(a, b){  
  return uppthis.sorrtingByArray.findIndex(x => x.Id == a.ByPramaeterSorted) - uppthis.sorrtingByArray.findIndex(x => x.Id == b.ByPramaeterSorted);
});

你可以这样做:

function getSorted(itemsArray , sortingArr ) {
  var result = [];
  for(var i=0; i<arr.length; i++) {
    result[i] = arr[sortArr[i]];
  }
  return result;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM