简体   繁体   English

如何使用 javascript 对间接数组进行排序?

[英]How can I sort an indirect array with 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
}

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).现在,我想对 arr2 进行排序,所以当我使用这种代码(在本段下)循环遍历它时,我会使用排序数组 (arr2) 中的索引访问 arr。

  arr[arr2[i]]

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.sort(function(a,b){arr[a] - arr[b]},但每次排序都不好。我尝试自己排序 function,但我的问题留了下来。

To summarize, I want to sort arr2 so when I loop through it, I get the value of arr in ascending (or descending) order.总而言之,我想对 arr2 进行排序,因此当我遍历它时,我会按升序(或降序)顺序获得 arr 的值。

EDIT I fixe this problem, but another appears, when I applied the arr2 on my html, the order mess up.编辑我解决了这个问题,但是当我在我的 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 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

You need to return the delta.您需要返回增量。 Otherwise the callback returns undefined for each call.否则,回调为每次调用返回undefined

arr2.sort(function(a, b) {
    return arr[b] - arr[a];
});

For adding the right order, you need ot take the index from indices to address the right element and assign i as style order value.为了添加正确的顺序,您不需要从索引中获取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>

functional arbitrary sort功能任意排序

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 -假设我们有一些fruits和我们希望对它们进行排序的任意order -

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

We wish up a Comparison module to handle our sorting code -我们希望有一个Comparison模块来处理我们的排序代码 -

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

Now we just have to implement Comparison -现在我们只需要实现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" ]


why a module?为什么是模块?

Implementing a Comparison module means we have a tidy place to store all of our comparison logic.实现一个Comparison模块意味着我们有一个整洁的地方来存储我们所有的比较逻辑。 We could easily implement other useful functions like reverse and concat now -我们现在可以轻松实现其他有用的功能,例如reverseconcat -

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 -现在我们可以轻松实现 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 }
  ]

Sort by name then sort by age -name排序,然后按age排序 -

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

Sort by age then sort by name -age排序,然后按name排序 -

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

And effortlessly reverse any sorter.并且毫不费力地reverse任何分拣机。 Here we sort by name then reverse sort by age -在这里,我们按name排序,然后按age反向排序 -

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

functional principles功能原理

Our Comparison module is flexible yet reliable.我们的Comparison模块既灵活又可靠。 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))

And similarly with concat expressions -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 nuts with nsort go 螺母带nsort

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 -例如,对日期对象进行排序需要三个比较: yearmonthday ——

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
    )

Now we can sort by year , month , day -现在我们可以按yearmonthday排序——

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

And just as easily reverse sort by year , month , day -就像按yearmonthday轻松反向排序一样——

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

Implementing N-sort is a breeze thanks to functional principles.由于功能原理,实现 N-sort 轻而易举。 Our concat and empty do all the hard work -我们的concatempty做了所有的努力——

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

Above Comparison and Ordered are defined as simple objects.以上ComparisonOrdered被定义为简单对象。 JavaScript is a very flexible language and import / export syntaxes were made explicitly available for modularising your programs. JavaScript 是一种非常灵活的语言, import / export语法明确可用于模块化您的程序。 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 -以这种方式编写模块让我们清楚地了解 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 }

Much Code, but it works:)很多代码,但它有效:)

For sort ASC:对于排序 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);

For sort DESC:对于排序 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);

Its much easy buddy use this arr.sort(function(a, b){return a - b});它很容易使用这个 arr.sort(function(a, b){return a - b}); // use return otherwise it will not triggered and - + plus denote ascndng dcndng ordee Simple method..... Happy coding // 使用 return 否则不会触发和 - + 加号表示 ascndng dcndng ordee 简单方法.....快乐编码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM