是否可以对如下所示的数组进行排序和重新排列:
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'],
]
知道如何做到这一点?
就像是:
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] })
我需要的东西就像你问的那样,我遇到了这个问题。这就是我正在寻找的东西,我根据另一个数组排序了一个阵列数组:
它是On ^ 3,可能不是最佳实践(ES6)
function sortArray(arr, arr1){
return arr.map(item => {
let a = [];
for(let i=0; i< arr1.length; i++){
for (const el of item) {
if(el == arr1[i]){
a.push(el);
}
}
}
return a;
});
}
const arr1 = ['fname', 'city', 'name'];
const arr = [['fname', 'city', 'name'],
['fname', 'city', 'name', 'name', 'city','fname']];
console.log(sortArray(arr,arr1));
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;
})
如果参考数组中不存在排序键,此解决方案将在末尾附加对象
使用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;
为了获得一个新的有序数组,您可以使用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);
你可以尝试这种方法。
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
}
为什么不喜欢
//array1: array of elements to be sorted
//array2: array with the indexes
array1 = array2.map((object, i) => array1[object]);
地图功能可能并非在所有版本的Javascript
上都可用
你可以这样做:
function getSorted(itemsArray , sortingArr ) {
var result = [];
for(var i=0; i<arr.length; i++) {
result[i] = arr[sortArr[i]];
}
return result;
}
注意:这假设您传入的数组大小相同,如果情况不同,则需要添加一些额外的检查。
请参阅link
使用两个数组的交集。
例如:
var sortArray = ['a', 'b', 'c', 'd', 'e'];
var arrayToBeSort = ['z', 's', 'b', 'e', 'a'];
_.intersection(sortArray, arrayToBeSort)
=> ['a','b','e']
如果'z和's'超出第一个数组的范围,则将其附加到结果的末尾
一线答案。
itemsArray.sort(function(a, b){
return sortingArr.indexOf(a) - sortingArr.indexOf(b);
});
许多其他有效的答案。 :)
var groups = _.groupBy(itemArray, 1);
var result = _.map(sortArray, function (i) { return groups[i].shift(); });
我猜大多数人来到这里寻找相当于PHP array_multisort(我做过)所以我想我也会发布那个答案。有几种选择:
1.现有JS implementation of array_multisort()。感谢@Adnan在评论中指出它。但它非常大。
写自己的。 (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或Underscore.js(两个流行的,重点关注性能的小型库)提供帮助函数,允许您执行此操作:
var result = _.chain(sortArray)
.pairs()
.sortBy(1)
.map(function (i) { return itemArray[i[0]]; })
.value();
...其中(1)将sortArray分组为[index, value]
对,(2)按值对它们进行排序(这里也可以提供回调),(3)用indexArray中的项目替换每个对这两个起源于。
如果使用本机数组排序功能,则可以传入自定义比较器以在排序数组时使用。如果第一个值小于第二个值,比较器应返回负数,如果它们相等则返回零,如果第一个值更大,则返回正数。
因此,如果我理解您正确给出的示例,您可以执行以下操作:
function sortFunc(a, b) {
var sortingArr = [ 'b', 'c', 'b', 'b', 'c', 'd' ];
return sortingArr.indexOf(a[1]) - sortingArr.indexOf(b[1]);
}
itemsArray.sort(sortFunc);
这可能为时已晚,但您也可以在ES6风格中使用下面代码的某些修改版本。此代码适用于以下数组:
var arrayToBeSorted = [1,2,3,4,5];
var arrayWithReferenceOrder = [3,5,8,9];
实际操作:
arrayToBeSorted = arrayWithReferenceOrder.filter(v => arrayToBeSorted.includes(v));
ES5中的实际操作:
arrayToBeSorted = arrayWithReferenceOrder.filter(function(v) {
return arrayToBeSorted.includes(v);
});
应该导致arrayToBeSorted = [3,5]
不破坏引用数组。
我会使用一个中间对象(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;
}
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;
}
}
}
结果顺序:鲍勃,杰森,亨利,托马斯,安妮,安德鲁
我必须为从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);
});
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)