Sort an array in the same order of another array

前端 未结 4 1102
长发绾君心
长发绾君心 2020-12-06 07:19

I have a few arrays of 50+ names like this.

[\"dan\", \"ryan\", \"bob\", \"steven\", \"corbin\"]
[\"bob\", \"dan\", \"steven\", \"corbin\"]

相关标签:
4条回答
  • 2020-12-06 07:24

    If you need to place values of your array in the recurring order, meaning:
    Input: [1, 2, 4, 4, 3, 3, 2, 1]
    Output: [1, 2, 3, 4, 1, 2, 3, 4]

    Then you can use 2 functions below. The first one uses the second one.
    For the first function you will need to provide 2 arguments:
    1st argument: your array of items that should be ordered (Input from above)
    2nd argument: array of the correct order ([1, 2, 3, 4] for the example above)

    function sortByOrder (array, order) {
    
        const arrayOfArrays = order.map(v => {
    
            return [...Array(howMany(v, array))].map(undef => v);
        });
    
        const tempArray = [];
    
        arrayOfArrays.forEach((subArr, i) => {
    
            let index = order.indexOf(order[i]);
    
            subArr.forEach(duplicate => {
    
                tempArray[index] = duplicate;
    
                index += order.length;
            });
        });
    
        return tempArray.filter(v => v);
    }
    
    function howMany(value, array) {
    
            const regExp = new RegExp(value, 'g');
    
            return (array.join(' ').match(regExp) || []).length;
    }
    
    0 讨论(0)
  • 2020-12-06 07:26

    You can realize some sorter by patter factory function. Then create sorter using your pattern and apply it to your arrays:

    function sorterByPattern(pattern) {
        var hash = {};
        pattern.forEach(function(name, index) { hash[name] = index });
    
        return function(n1, n2) {
            if (!(n1 in hash)) return 1;  // checks if name is not in the pattern
            if (!(n2 in hash)) return -1; // if true - place that names to the end
            return hash[n1] - hash[n2];
        }
    }
    
    var sorter = sorterByPattern(["ryan", "corbin", "dan", "steven", "bob"]);
    
    var arrays = [
        ["dan", "ryan", "bob", "steven", "corbin"],
        ["bob", "dan", "steven", "corbin"]
        /* ... */
    ];
    
    arrays.forEach(function(array) { array.sort(sorter) });
    
    0 讨论(0)
  • 2020-12-06 07:47

    Use indexOf() to get the position of each element in the reference array, and use that in your comparison function.

    var reference_array = ["ryan", "corbin", "dan", "steven", "bob"];
    var array = ["bob", "dan", "steven", "corbin"];
    array.sort(function(a, b) {
      return reference_array.indexOf(a) - reference_array.indexOf(b);
    });
    console.log(array); // ["corbin", "dan", "steven", "bob"]

    Searching the reference array every time will be inefficient for large arrays. If this is a problem, you can convert it into an object that maps names to positions:

    var reference_array = ["ryan", "corbin", "dan", "steven", "bob"];
    reference_object = {};
    for (var i = 0; i < reference_array.length; i++) {
        reference_object[reference_array[i]] = i;
    }
    var array = ["bob", "dan", "steven", "corbin"];
    array.sort(function(a, b) {
      return reference_object[a] - reference_object[b];
    });
    console.log(array);

    0 讨论(0)
  • 2020-12-06 07:50

    I had the same issue now and I tried a bit different approach. It does not sort the arrays but filtering the order-list according to sorting-lists so it has got some limitations but for my needs it's event better because it gets rid of incorrect values from sorted list:

    • if sorting-list has got doubled value, it will occure just once in sorted list
    • if sorting-list has got item which is not included in order-list, it will not appear in sorted list

    function sortOrder(getOrder,getArr){
      return getOrder.filter(function(order){
        return getArr.some(function(list){
          return order === list;
        });
      });
    }
    
    //arrays
    var order = ["ryan", "corbin", "dan", "steven", "bob"];
    var arA = ["dan", "ryan", "bob", "steven", "corbin"];
    var arB = ["bob", "dan", "steven", "corbin"];
    var arC = ["bob","ryan"];
    var arD = ["bob","bob","corbin"]; //remove repetition
    var arE = ["unrecognizedItem","corbin","steven","ryan"]; //remove the item not included in order array
    
    //print results
    document.body.innerHTML = sortOrder(order,arA)+'<br/>';
    document.body.innerHTML += sortOrder(order,arB)+'<br/>';
    document.body.innerHTML += sortOrder(order,arC)+'<br/>';
    document.body.innerHTML += sortOrder(order,arD)+'<br/>';
    document.body.innerHTML += sortOrder(order,arE)+'<br/>';

    0 讨论(0)
提交回复
热议问题