[英]How can I sort an indirect array with javascript?
在我的项目中,我需要对包含另一个数组(它是项)的索引的数组进行排序。 我已经搜索了很多小时,但我没有找到任何有我的问题的人。
var arr = [1, 4, 3, 4, 5, 6, 7, 8, 9];
function sorting(){
let arr2 = [0, 1, 2, 3, 4, 5, 6, 7, 8];
//sorting code
}
现在,我想对 arr2 进行排序,所以当我使用这种代码(在本段下)循环遍历它时,我会使用排序数组 (arr2) 中的索引访问 arr。
arr[arr2[i]]
我的第一步是使用 arr2.sort(function(a,b){arr[a] - arr[b]},但每次排序都不好。我尝试自己排序 function,但我的问题留了下来。
总而言之,我想对 arr2 进行排序,因此当我遍历它时,我会按升序(或降序)顺序获得 arr 的值。
编辑我解决了这个问题,但是当我在我的 html 上应用 arr2 时,出现了另一个问题,订单混乱了。
var arr = [1, 4, 3, 4, 5, 6, 7, 8, 9];
function sorting(){
let arr2 = [0, 1, 2, 3, 4, 5, 6, 7, 8];
//The sorting block code (done)
z = document.getElementsByClassName("triable"); //this is on what I applied arr2
for (let i = 0; i < z.length; i++){
z[i].style.order = arr2[i]; //this line work, but doesn't correctly do what I what it to do
}
}
For html, I have some div with a class "triable" and the code above this need to applied a css style (order) so the div visually change of position
您需要返回增量。 否则,回调为每次调用返回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>
功能任意排序
这是解决您的问题的另一种方法。 假设我们有一些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
}
现在我们可以轻松实现 model 复杂的排序逻辑——
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)
go 螺母带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-sort 轻而易举。 我们的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
语法明确可用于模块化您的程序。 以这种方式编写模块让我们清楚地了解 go 的位置,并为我们提供了足够的空间来扩展我们的代码 -
// 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 }
很多代码,但它有效:)
对于排序 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);
它很容易使用这个 arr.sort(function(a, b){return a - b}); // 使用 return 否则不会触发和 - + 加号表示 ascndng dcndng ordee 简单方法.....快乐编码
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.