4 回答

TA貢獻1943條經驗 獲得超7個贊
函數任意排序
這是解決您的問題的另一種方法。假設我們有一些fruits并且任意的order我們希望對它們進行排序 -
const fruits =
// 0 1 2 3 4
[ "apple", "banana", "cherry", "orange", "peach" ]
const order =
[ 1, 3, 2, 0, 4 ]
我們希望能夠寫出這樣的東西 -
fruits.sort(sortByIndex(fruits, order))
console.log(fruits)
// [ "banana", "orange", "cherry", "apple", "peach" ]
// 1 3 2 0 4
我們希望有一個Comparison模塊來處理我們的排序代碼 -
const { empty, map } =
Comparison
const sortByIndex = (values = [], indexes = []) =>
map(empty, x => indexes.indexOf(values.indexOf(x)))
現在我們只需要實施Comparison-
const Comparison =
{ empty: (a, b) =>
a < b ? -1
: a > b ? 1
: 0
, map: (m, f) =>
(a, b) => m(f(a), f(b))
}
const { empty, map } =
Comparison
const sortByIndex = (values = [], indexes = []) =>
map(empty, x => indexes.indexOf(values.indexOf(x)))
const fruits =
[ "apple", "banana", "cherry", "orange", "peach" ]
// 0 1 2 3 4
const order =
[ 1, 3, 2, 0, 4 ]
console.log(fruits)
// [ "apple", "banana", "cherry", "orange", "peach" ]
console.log(fruits.sort(sortByIndex(fruits, order)))
// [ "banana", "orange", "cherry", "apple", "peach" ]
為什么是模塊?
實現一個Comparison模塊意味著我們有一個整潔的地方來存儲所有的比較邏輯。我們可以輕松實現其他有用的功能,例如reverse現在concat-
const Comparison =
{ // ...
, concat: (m, n) =>
(a, b) => Ordered.concat(m(a, b), n(a, b))
, reverse: (m) =>
(a, b) => m(b, a)
}
const Ordered =
{ empty: 0
, concat: (a, b) =>
a === 0 ? b : a
}
現在我們可以輕松地對復雜的排序邏輯進行建模 -
const sortByName =
map(empty, x => x.name)
const sortByAge =
map(empty, x => x.age)
const data =
[ { name: 'Alicia', age: 10 }
, { name: 'Alice', age: 15 }
, { name: 'Alice', age: 10 }
, { name: 'Alice', age: 16 }
]
排序依據name然后排序依據age-
data.sort(concat(sortByName, sortByAge))
// [ { name: 'Alice', age: 10 }
// , { name: 'Alice', age: 15 }
// , { name: 'Alice', age: 16 }
// , { name: 'Alicia', age: 10 }
// ]
排序依據age然后排序依據name-
data.sort(concat(sortByAge, sortByName))
// [ { name: 'Alice', age: 10 }
// , { name: 'Alicia', age: 10 }
// , { name: 'Alice', age: 15 }
// , { name: 'Alice', age: 16 }
// ]
并且毫不費力地reverse進行任何分類。在這里我們排序name然后反向排序age-
data.sort(concat(sortByName, reverse(sortByAge)))
// [ { name: 'Alice', age: 16 }
// , { name: 'Alice', age: 15 }
// , { name: 'Alice', age: 10 }
// , { name: 'Alicia', age: 10 }
// ]
功能原理
我們的Comparison模塊靈活而可靠。這使我們能夠以類似公式的方式編寫排序器 -
// this...
concat(reverse(sortByName), reverse(sortByAge))
// is the same as...
reverse(concat(sortByName, sortByAge))
與concat表達式類似 -
// this...
concat(sortByYear, concat(sortByMonth, sortByDay))
// is the same as...
concat(concat(sortByYear, sortByMonth), sortByDay)
// is the same as...
nsort(sortByYear, sortByMonth, sortByDay)
發瘋nsort
現在假設我們要按任意數量的因素進行排序。例如,對日期對象進行排序需要三個比較:year、month和day-
const { empty, map, reverse, nsort } =
Comparison
const data =
[ { year: 2020, month: 4, day: 5 }
, { year: 2018, month: 1, day: 20 }
, { year: 2019, month: 3, day: 14 }
]
const sortByDate =
nsort
( map(empty, x => x.year) // primary: sort by year
, map(empty, x => x.month) // secondary: sort by month
, map(empty, x => x.day) // tertiary: sort by day
)
現在我們可以按year, month, day-排序
data.sort(sortByDate)
// [ { year: 2019, month: 11, day: 14 }
// , { year: 2020, month: 4, day: 3 }
// , { year: 2020, month: 4, day: 5 }
// ]
并且同樣可以輕松地按year, month, day-進行反向排序
data.sort(reverse(sortByDate))
// [ { year: 2020, month: 4, day: 5 }
// , { year: 2020, month: 4, day: 3 }
// , { year: 2019, month: 11, day: 14 }
// ]
由于功能原理,實現 N 排序變得輕而易舉。我們concat并empty盡一切努力——
const Comparison =
{ // ...
, nsort: (...m) =>
m.reduce(Comparison.concat, Comparison.empty)
}
展開下面的代碼片段以查看此代碼的實際效果 -
const Comparison =
{ empty: (a, b) =>
a < b ? -1
: a > b ? 1
: 0
, map: (m, f) =>
(a, b) => m(f(a), f(b))
, concat: (m, n) =>
(a, b) => Ordered.concat(m(a, b), n(a, b))
, reverse: (m) =>
(a, b) => m(b, a)
, nsort: (...m) =>
m.reduce(Comparison.concat, Comparison.empty)
}
const Ordered =
{ empty: 0
, concat: (a, b) =>
a === 0 ? b : a
}
const { empty, map, concat, reverse, nsort } =
Comparison
const sortByDate =
nsort
( map(empty, x => x.year) // primary
, map(empty, x => x.month) // secondary
, map(empty, x => x.day) // tertiary
)
const data =
[ { year: 2020, month: 4, day: 5 }
, { year: 2019, month: 11, day: 14 }
, { year: 2020, month: 4, day: 3 }
]
console.log(data.sort(reverse(sortByDate)))
// [ { year: 2020, month: 4, day: 5 }
// , { year: 2020, month: 4, day: 3 }
// , { year: 2019, month: 11, day: 14 }
// ]
JavaScript 模塊
上面Comparison和Ordered被定義為簡單對象。JavaScript 是一種非常靈活的語言,并且import語法export明確可用于模塊化您的程序。以這種方式編寫模塊可以讓我們清楚地了解事情應該去哪里,并為我們提供足夠的空間來擴展我們的代碼 -
// Comparison.js
import { lt, gt, eq, concat:_concat } from "./Ordered"
const asc = (a, b) =>
(console.log(a, b), a < b) ? lt
: a > b ? gt
: eq
const empty =
asc
const map = (m, f) =>
(a, b) => m(f(a), f(b))
const concat = (m, n) =>
(a, b) => _concat(m(a, b), n(a, b))
const reverse = (m) =>
(a, b) => m(b, a)
const desc =
reverse(asc)
export { asc, concat, desc, empty, map, reverse }
// Ordered.js
const lt =
-1
const gt =
1
const eq =
0
const empty =
eq
const concat = (a, b) =>
a === eq ? b : a
export { concat, empty, eq, gt, lt }

TA貢獻1848條經驗 獲得超2個贊
您需要返回增量。undefined否則,每次調用都會返回回調。
arr2.sort(function(a, b) {
return arr[b] - arr[a];
});
為了添加正確的順序,您不需要獲取索引來indices尋址正確的元素并指定i為樣式順序值。
function sort() {
var array = [1, 4, 3, 4, 5, 6, 7, 8, 9],
z = document.getElementsByClassName("triable");
[...array.keys()]
.sort((a, b) => array[b] - array[a])
.forEach((v, i) => z[v].style.order = i);
}
<button onclick="sort()">sort</button><br>
<div style="display: flex;">
<span class="triable">1</span>
<span class="triable">4</span>
<span class="triable">3</span>
<span class="triable">4</span>
<span class="triable">5</span>
<span class="triable">6</span>
<span class="triable">7</span>
<span class="triable">8</span>
<span class="triable">9</span>
</div>

TA貢獻1825條經驗 獲得超6個贊
代碼很多,但有效:)
對于 ASC 排序:
var test = [1, 4, 3, 4, 5, 6, 7, 8, 9];
console.log("Original Array: " + test);
var len = test.length;
var indices = new Array(len);
for (var i = 0; i < len; ++i) indices[i] = i;
indices.sort(function (a, b) { return test[a] < test[b] ? -1 : test[a] > test[b] ? 1 : 0; });
test.sort();
console.log("Sort-ASC " + test);
console.log("Index from Array " + indices);
對于 DESC 排序:
var test = [1, 4, 3, 4, 5, 6, 7, 8, 9];
console.log("Originales Array: " + test)
var len = test.length;
var indices = new Array(len);
for (var i = 0; i < len; ++i) indices[i] = i;
indices.sort(function (a, b) { return test[a] < test[b] ? -1 : test[a] > test[b] ? 1 : 0; });
indices.reverse();
test.sort();
test.reverse();
console.log("Sort-DESC " + test);
console.log("Index from Array " + indices);

TA貢獻1860條經驗 獲得超9個贊
使用這個 arr.sort(function(a, b){return a - b}); 很簡單。// 使用 return 否則不會觸發 - + 加號表示 ascndng dcndng ordee 簡單方法 ..... 快樂編碼
- 4 回答
- 0 關注
- 178 瀏覽
添加回答
舉報