简体   繁体   中英

Sort multiple arrays based on one array

I have an array of javascript arrays, with each inner array being of equal length. I want to sort one of the inner arrays chronologically (its members are all numbers), and I want the other arrays to re-order in the same way. Eg

we start with this:

[[2, 3, 1], ["deux", "trois", "un"], ["zwei", "drei", "eins"]]

and the result I want is:

[[1, 2, 3], ["un", "deux", "trois"], ["eins", "zwei", "drei"]]

I've tried different variations on the following, but had no luck:

arr.sort((a, b) => a[0] - b[0])

All I get back is exactly what I put in!

This should do the trick, we should get the new indexes for array of numbers then apply the same new indexes to non number arrays:

 const arrays = [ [2, 3, 1], ["deux", "trois", "un"], ["zwei", "drei", "eins"], ]; const [arrNbrs] = arrays; const newIndexes = [...arrNbrs].sort().map((nbr) => arrNbrs.indexOf(nbr)); const sortedArrays = arrays.map((subArray) => subArray.map((_, index) => subArray[newIndexes[index]]) ); console.log("sortedArrays", sortedArrays);

You could get an array of sorted indices and map sorted arrays.

 const arrays = [[2, 3, 1], ["deux", "trois", "un"], ["zwei", "drei", "eins"]], sorted = arrays.map( (indices => a => indices.map(i => a[i])) ([...arrays[0].keys()].sort((a, b) => arrays[0][a] - arrays[0][b])) ); console.log(sorted);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

A function for it.

 const sortNumbers = (a, b) => a - b, sortABC = (a, b) => a.localeCompare(b), sortArray = (arrays, index, fn) => { const source = arrays[index], indices = [...source.keys()].sort((a, b) => fn(source[a], source[b])); return arrays.map(a => indices.map(i => a[i])); }, arrays = [[2, 3, 1], ["deux", "trois", "un"], ["zwei", "drei", "eins"]], sorted0 = sortArray(arrays, 0, sortNumbers), sorted1 = sortArray(arrays, 1, sortABC); sorted2 = sortArray(arrays, 2, sortABC); console.log(sorted0); console.log(sorted1); console.log(sorted2);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

 const test = [ [3, 2, 1, 3, 2, 1, 2], ["trois", "deux", "un", "trois", "deux", "un", "deux"], ["drei", "zwei", "eins", "drei", "zwei", "eins", "zwei"] ]; function sortListsAccordingToReferenceList( listOfLists, listIndex, referenceComparator ) { function defaultComparator(a, b) { return ( ((a.localeCompare) && (b.localeCompare))? a.localeCompare(b): (((a < b) && -1) || ((a > b) && 1) || 0) ); } const comparator = (typeof referenceComparator === 'function')? referenceComparator: defaultComparator; function compareReferenceItems(a, b) { return comparator(a.value, b.value); } const referenceList = listOfLists[listIndex]; const lastIndexList = referenceList.map((item, idx) => ({ lastIndex: idx, value: item })).sort(compareReferenceItems).map(referenceItem => referenceItem.lastIndex ); // console.log('lastIndexList: ', lastIndexList); // - in case of needing to return the // mutated original array use this block... // // listOfLists.forEach((list, idx) => { // // const duplicates = Array.from(list); // lastIndexList.forEach((lastIndex, idx) => { // // list[idx] = duplicates[lastIndex]; // }); // }); // return listOfLists; // return mutated original array. // -... otherwise go with pure mappping. return listOfLists.map(list => list.map((item, idx) => list[lastIndexList[idx]]) ); } console.log( 'sort every array according to numeric sort order...', sortListsAccordingToReferenceList(test, 0) ); console.log( 'sort everything by French as lexicographic sort reference...', sortListsAccordingToReferenceList(test, 1) ); console.log( 'sort everything by German as lexicographic sort reference...', sortListsAccordingToReferenceList(test, 2) ); console.log( 'sort every array according to numeric custom sort order...', sortListsAccordingToReferenceList(test, 0, (a, b) => // comparator function for descending sort order (((a > b) && -1) || ((a < b) && 1) || 0) ) );
 .as-console-wrapper { min-height: 100%;important: top; 0; }

Not a oneliner, but easier to read

 let nested = [ [2, 3, 1], ["deux", "trois", "un"], ["zwei", "drei", "eins"] ]; let srcArr; nested = nested.map((arr, i) => { if (i === 0) { // the reference srcArr = arr.slice(0); // take a copy arr.sort((a, b) => a - b); // sort the nested one return arr; } return arr.map((item, i) => arr[ srcArr.indexOf(nested[0][i]) // return in the order of the reference ]); }) console.log(nested)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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