Sort two arrays the same way

前端 未结 12 2270
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-27 15:48

For example, if I have these arrays:

var name = [\"Bob\",\"Tom\",\"Larry\"];
var age =  [\"10\", \"20\", \"30\"];

And I use name.sort

12条回答
  •  伪装坚强ぢ
    2020-11-27 16:37

    This solution (my work) sorts multiple arrays, without transforming the data to an intermediary structure, and works on large arrays efficiently. It allows passing arrays as a list, or object, and supports a custom compareFunction.

    Usage:

    let people = ["john", "benny", "sally", "george"];
    let peopleIds = [10, 20, 30, 40];
    
    sortArrays([people, peopleIds]);
    [["benny", "george", "john", "sally"], [20, 40, 10, 30]] // output
    
    sortArrays({people, peopleIds});
    {"people": ["benny", "george", "john", "sally"], "peopleIds": [20, 40, 10, 30]} // output
    
    

    Algorithm:

    • Create a list of indexes of the main array (sortableArray)
    • Sort the indexes with a custom compareFunction that compares the values, looked up with the index
    • For each input array, map each index, in order, to its value

    Implementation:

    /**
     *  Sorts all arrays together with the first. Pass either a list of arrays, or a map. Any key is accepted.
     *     Array|Object arrays               [sortableArray, ...otherArrays]; {sortableArray: [], secondaryArray: [], ...}
     *     Function comparator(?,?) -> int   optional compareFunction, compatible with Array.sort(compareFunction)
     */
    function sortArrays(arrays, comparator = (a, b) => (a < b) ? -1 : (a > b) ? 1 : 0) {
        let arrayKeys = Object.keys(arrays);
        let sortableArray = Object.values(arrays)[0];
        let indexes = Object.keys(sortableArray);
        let sortedIndexes = indexes.sort((a, b) => comparator(sortableArray[a], sortableArray[b]));
    
        let sortByIndexes = (array, sortedIndexes) => sortedIndexes.map(sortedIndex => array[sortedIndex]);
    
        if (Array.isArray(arrays)) {
            return arrayKeys.map(arrayIndex => sortByIndexes(arrays[arrayIndex], sortedIndexes));
        } else {
            let sortedArrays = {};
            arrayKeys.forEach((arrayKey) => {
                sortedArrays[arrayKey] = sortByIndexes(arrays[arrayKey], sortedIndexes);
            });
            return sortedArrays;
        }
    }
    

    See also https://gist.github.com/boukeversteegh/3219ffb912ac6ef7282b1f5ce7a379ad

提交回复
热议问题