2017-02-22 88 views
1

基本上我希望重複的值上升到最高,然後讓剩下的值從小到大排序(升序)。什麼,我需要Javascript首先重複排序,然後再從小到大排序

例子:

246, 246, 246, 100, 216, 553, 600 

這是我的代碼輸出:

100, 216, 246, 246, 246, 553, 600 

這裏是我的代碼:

Javascript Demo on JSBin

// Array of objects 
var unsorted = [ 
    { 
     id: 1, 
     height: 600 
    }, 
    { 
     id: 2, 
     height: 246 
    }, 
    { 
     id: 3, 
     height: 216 
    }, 
    { 
     id: 4, 
     height: 100 
    }, 
    { 
     id: 5, 
     height: 553 
    }, 
    { 
     id: 7, 
     height: 246 
    }, 
    { 
     id: 6, 
     height: 246 
    } 
]; 


// Sort by duplicates, then ascending 
var sorted = unsorted.sort(function(a, b) { 

    // Attempting to sort duplicates first... 
    if (a.height === b.height) { 
     return -1; 
    } 

    if (a.height < b.height) { 
     return -1; 
    } 

    if (a.height > b.height) { 
     return 1; 
    } 

    return 0; 
}); 

console.log(sorted); 

回答

0

這裏是你可以使用不ES6風格寫了一個替代的解決方案,通過分組複製到一個數組和不同的值到另一個陣列,單獨地分選各那些然後連接兩者:

function duplicateSort(objects) { 
 

 
    // ordering from smallest to largest 
 
    var ascending = function(prev, next) { 
 
    return prev.height - next.height; 
 
    }; 
 

 
    // sorts an arr with an ascending ordering 
 
    var ascendingSort = function(arr) { 
 
    return arr.sort(ascending); 
 
    }; 
 

 
    // checks if item is a duplicate 
 
    var isDuplicate = function(item) { 
 
    return objects.filter(function(obj) { 
 
     return obj.height == item.height 
 
    }).length == 1 ? false : true; 
 
    } 
 

 
    // checks if item is not a duplicate 
 
    var notDuplicate = function(item) { 
 
    return !isDuplicate(item); 
 
    } 
 

 
    // partition duplicates vs distinct 
 
    var duplicates = objects.filter(isDuplicate); 
 
    var nonDuplicates = objects.filter(notDuplicate); 
 

 
    // sort both and flatten/concat into one array 
 
    return [].concat.apply([], [duplicates, nonDuplicates].map(ascendingSort)); 
 
} 
 

 

 

 
var unsorted = [{ 
 
    id: 1, 
 
    height: 600 
 
    }, 
 
    { 
 
    id: 2, 
 
    height: 246 
 
    }, 
 
    { 
 
    id: 3, 
 
    height: 216 
 
    }, 
 
    { 
 
    id: 4, 
 
    height: 100 
 
    }, 
 
    { 
 
    id: 5, 
 
    height: 553 
 
    }, 
 
    { 
 
    id: 6, 
 
    height: 246 
 
    } 
 
]; 
 

 
console.log(duplicateSort(unsorted));

使用sort的溶液將被寫入一個比較器通過移動它朝着array的前部並且通常分選不同的值(升序)來處理一個duplicate項。由於sort每次只檢查2個數字,所以將這種排序應用於數組長度。

function duplicateSort2(arr) { 
 

 
    // checks if element is a duplicate in this array 
 
    var isDuplicate = function(item) { 
 
    return arr.filter(function(obj) { 
 
     return obj.height == item.height 
 
    }).length == 1 ? false : true; 
 
    } 
 

 
    // custom sort for duplicates 
 
    var ascending = function(prev, next) { 
 
    if (isDuplicate(prev)) return 0; 
 
    if (isDuplicate(next)) return 1; 
 
    return prev.height - next.height; 
 
    } 
 

 
    // sort on each element 
 
    arr.map(function(item) { 
 
    return arr.sort(ascending); 
 
    }); 
 

 
    return arr; 
 
} 
 

 
var unsorted = [{id: 1,height: 600},{id: 2,height: 246},{id: 3,height: 216},{id: 4,height: 100},{id: 5,height: 553},{id: 6,height: 246}]; 
 

 
console.log(duplicateSort2(unsorted));

+0

爲了一致起見,我不想混合ES6代碼與我目前的代碼...但我很欣賞答案...我想知道是否有一個更簡單的解決方案呢? – stwhite

+1

我重構了這個爲你匹配你的語法首選項。 –

0

改變你的排序功能,這一點 -

var sorted = unsorted.sort(function(a, b) { 

    // Attempting to sort duplicates first... 
    if (a.height === b.height) { 
     return -1; 
    } 

    if (a.height < b.height) { 
     return 0; 
    } 

    if (a.height > b.height) { 
     return 1; 
    } 

    return 0; 
}); 

console.log(sorted); 
+0

嗯......只是試圖實現這一點,似乎忽略重複,只有升序排列。 http://jsbin.com/vafitafoja/1/edit?js,output – stwhite

1

使用ES6 sort的回調函數,

const sortFunc = (a, b) => { 
    const diff = a.height - b.height; 
    switch (diff) { 
    case 0: 
     return -1; 
    default: 
     return diff; 
    } 
} 

unsortedArr.sort(sortFunc); 
+0

目前不使用ES6 ... – stwhite

+0

您應該使用它。如果你不想要,你可以使用babel在線手動將代碼轉移到ES5 –

+0

當然,但這不是我現在使用的 - 最終我會。此外,我只是在JS bin中運行這個函數,並且它不會首先輸出重複項... http://jsbin.com/wocekubote/1/edit?js,output – stwhite

0

運行下面的代碼會給你你想要的結果。 策略:製作兩個數組:唯一成員數組,重複成員數組。對它們進行排序然後將它們連接在一起。

// Array of objects 
 
var unsorted = [ 
 
    { 
 
     id: 1, 
 
     height: 600 
 
    }, 
 
    { 
 
     id: 2, 
 
     height: 246 
 
    }, 
 
    { 
 
     id: 3, 
 
     height: 216 
 
    }, 
 
    { 
 
     id: 4, 
 
     height: 100 
 
    }, 
 
    { 
 
     id: 5, 
 
     height: 553 
 
    }, 
 
    { 
 
     id: 7, 
 
     height: 246 
 
    }, 
 
    { 
 
     id: 6, 
 
     height: 246 
 
    } 
 
]; 
 

 

 
var uniqueHeights = []; 
 
var dupHeights = []; 
 
var findIndexByHeight = function(arr, ele) { 
 
    var index = -1; 
 
    arr.forEach(function(innerEle, innerI) { 
 
    if (ele.height === innerEle.height) { 
 
     index = innerI; 
 
    } 
 
    }); 
 
    return index; 
 
} 
 

 
unsorted.forEach(function(ele, i) { 
 
    if(findIndexByHeight(uniqueHeights, ele) === -1) { 
 
    uniqueHeights.push(ele); 
 
    } else { 
 
    dupHeights.push(ele); 
 
    } 
 
}); 
 

 
for(var idx = 0; idx < uniqueHeights.length; idx++) { 
 
    var dupIdx = findIndexByHeight(dupHeights, uniqueHeights[idx]); 
 
    if(dupIdx !== -1) { 
 
    dupHeights.push(uniqueHeights.splice(dupIdx, 1)[0]); 
 
    idx--; 
 
    } 
 
} 
 
var sortedDup = dupHeights.sort(function(a, b){ 
 
    return a.id > b.id; 
 
}); 
 
sortedDup = dupHeights.sort(function(a, b){ 
 
    return a.height > b.height; 
 
}); 
 
var sortedUnique = uniqueHeights.sort(function(a, b){ 
 
    return a.height > b.height; 
 
}); 
 
var resArr = sortedDup.concat(sortedUnique); 
 

 
console.log(resArr);

相關問題