簡體   English   中英

如何使用 javascript 對間接數組進行排序?

[英]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模塊意味着我們有一個整潔的地方來存儲我們所有的比較邏輯。 我們現在可以輕松實現其他有用的功能,例如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
  }

現在我們可以輕松實現 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

現在假設我們要按任意數量的因素進行排序。 例如,對日期對象進行排序需要三個比較: 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
    )

現在我們可以按yearmonthday排序——

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

就像按yearmonthday輕松反向排序一樣——

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做了所有的努力——

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

以上ComparisonOrdered被定義為簡單對象。 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM