How to sort an array of objects by multiple fields?

后端 未结 30 2866
北恋
北恋 2020-11-21 11:34

From this original question, how would I apply a sort on multiple fields?

Using this slightly adapted structure, how would I sort city (ascending) & then price (

30条回答
  •  我在风中等你
    2020-11-21 12:11

    A dynamic way to do that with MULTIPLE keys:

    • filter unique values from each col/key of sort
    • put in order or reverse it
    • add weights width zeropad for each object based on indexOf(value) keys values
    • sort using caclutated weights

    Object.defineProperty(Array.prototype, 'orderBy', {
    value: function(sorts) { 
        sorts.map(sort => {            
            sort.uniques = Array.from(
                new Set(this.map(obj => obj[sort.key]))
            );
    
            sort.uniques = sort.uniques.sort((a, b) => {
                if (typeof a == 'string') {
                    return sort.inverse ? b.localeCompare(a) : a.localeCompare(b);
                }
                else if (typeof a == 'number') {
                    return sort.inverse ? (a < b) : (a > b ? 1 : 0);
                }
                else if (typeof a == 'boolean') {
                    let x = sort.inverse ? (a === b) ? 0 : a? -1 : 1 : (a === b) ? 0 : a? 1 : -1;
                    return x;
                }
                return 0;
            });
        });
    
        const weightOfObject = (obj) => {
            let weight = "";
            sorts.map(sort => {
                let zeropad = `${sort.uniques.length}`.length;
                weight += sort.uniques.indexOf(obj[sort.key]).toString().padStart(zeropad, '0');
            });
            //obj.weight = weight; // if you need to see weights
            return weight;
        }
    
        this.sort((a, b) => {
            return weightOfObject(a).localeCompare( weightOfObject(b) );
        });
    
        return this;
    }
    });
    

    Use:

    // works with string, number and boolean
    let sortered = your_array.orderBy([
        {key: "type", inverse: false}, 
        {key: "title", inverse: false},
        {key: "spot", inverse: false},
        {key: "internal", inverse: true}
    ]);
    

提交回复
热议问题