如何使用javascript对间接数组进行排序? [英] How can I sort an indirect array with javascript?

查看:23
本文介绍了如何使用javascript对间接数组进行排序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的项目中,我需要对包含另一个数组(它的项目)索引的数组进行排序.我已经搜索了很多小时,但没有找到任何人遇到我的问题.

In my project, I need to sort an array that contain index of an other array (it's item). I've search for many hours, but I did not find anyone with my problem.

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.

Now, I want to sort arr2, so when I loop through it with this kind of code (under this paragraph), I access arr with the index in the sorted array (arr2).

  arr[arr2[i]]

我的第一步是使用arr2.sort(function(a,b){arr[a] - arr[b]},但每次排序都不好.我尝试制作自己的排序函数,但我的问题仍然存在.

My first move was to use arr2.sort(function(a,b){arr[a] - arr[b]}, but each time the sort wasn't good. I attempt to make my own sorting function, but my problem stayed.

总而言之,我想对 arr2 进行排序,这样当我循环遍历它时,我会按升序(或降序)获得 arr 的值.

To summarize, I want to sort arr2 so when I loop through it, I get the value of arr in ascending (or descending) order.

EDIT 我解决了这个问题,但另一个问题出现了,当我在我的 html 上应用 arr2 时,顺序搞砸了.

EDIT I fixe this problem, but another appears, when I applied the arr2 on my html, the order mess up.

    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
        }
    }

对于html,我有一些带有triable"类的div,上面的代码需要应用css样式(顺序),以便div在视觉上改变位置

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

推荐答案

函数式任意排序

这是解决您的问题的另一种方法.假设我们有一些 fruits 和一个任意的 order 我们希望将它们排序 -

Here's another way to approach your problem. Let's say we have some fruits and an arbitrary order we wish to sort them in -

const fruits =
  //   0        1          2        3         4 
  [ "apple", "banana", "cherry", "orange", "peach" ]
  

const order =
  [ 1, 3, 2, 0, 4 ]

我们希望能够写出这样的东西 -

We want to be able to write something like this -

fruits.sort(sortByIndex(fruits, order))

console.log(fruits)
// [ "banana", "orange", "cherry", "apple", "peach" ]
//      1         3         2         0        4

我们希望有一个 Comparison 模块来处理我们的排序代码 -

We wish up a Comparison module to handle our sorting code -

const { empty, map } =
  Comparison
  
const sortByIndex = (values = [], indexes = []) =>
  map(empty, x => indexes.indexOf(values.indexOf(x)))

现在我们只需要实现Comparison -

Now we just have to implement 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 模块意味着我们有一个整洁的地方来存储我们所有的比较逻辑.我们现在可以轻松实现其他有用的功能,例如 reverseconcat -

Implementing a Comparison module means we have a tidy place to store all of our comparison logic. We could easily implement other useful functions like reverse and concat now -

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
  }

现在我们可以轻松地对复杂的排序逻辑进行建模 -

Now we can model complex sorting logic with ease -

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 }
// ]

并且毫不费力地反转任何分拣机.这里我们按name排序,然后按age反向排序-

And effortlessly reverse any sorter. Here we sort by name then reverse sort by age -

data.sort(concat(sortByName, reverse(sortByAge)))
// [ { name: 'Alice', age: 16 }
// , { name: 'Alice', age: 15 }
// , { name: 'Alice', age: 10 }
// , { name: 'Alicia', age: 10 }
// ]

功能原则

我们的Comparison 模块灵活而可靠.这允许我们以类似公式的方式编写排序器 -

Our Comparison module is flexible yet reliable. This allows us to write our sorters in a formula-like way -

// 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

现在假设我们要按任意数量的因子进行排序.例如,对日期对象进行排序需要三个比较:yearmonthday -

Now let's say we want to sort by an arbitrary number of factors. For example, sorting date objects requires three comparisons: year, month, and 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
    )

现在我们可以按yearmonthday -

Now we can sort by year, month, day -

data.sort(sortByDate)
// [ { year: 2019, month: 11, day: 14 }
// , { year: 2020, month: 4, day: 3 }
// , { year: 2020, month: 4, day: 5 }
// ]

同样容易地按yearmonthday进行反向排序-

And just as easily reverse sort by 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 变得轻而易举.我们的 concatempty 完成了所有艰苦的工作 -

Implementing N-sort is a breeze thanks to functional principles. Our concat and empty do all the hard work -

const Comparison =
  { // ...
  , nsort: (...m) =>
      m.reduce(Comparison.concat, Comparison.empty)
  }

展开下面的代码片段以查看此代码的实际效果 -

Expand the snippet below to see this code in action -

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 模块

上面的ComparisonOrdered 被定义为简单的对象.JavaScript 是一种非常灵活的语言,import/export 语法明确可用于模块化您的程序.以这种方式编写模块可以让我们清楚地了解事情的发展方向,并为我们提供了足够的空间来增长我们的代码 -

Above Comparison and Ordered are defined as simple objects. JavaScript is a very flexible language and import/export syntaxes were made explicitly available for modularising your programs. Writing modules in this way gives us a clear picture of where things should go and provides us with plenty of room to grow our code -

// 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 }

这篇关于如何使用javascript对间接数组进行排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆