Как я могу отсортировать косвенный массив с javascript? - PullRequest
1 голос
/ 05 апреля 2020

В моем проекте мне нужно отсортировать массив, который содержит индекс другого массива (это элемент). Я искал много часов, но я не нашел никого с моей проблемой.

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, поэтому, когда я oop просматриваю его с таким кодом ( согласно этому пункту), я получаю доступ к arr с индексом в отсортированном массиве (arr2).

  arr[arr2[i]]

Моим первым шагом было использование arr2.sort (function (a, b) {arr [a] - arr [b]}, но каждый раз сортировка была неудачной. Я пытаюсь создать собственную функцию сортировки, но моя проблема осталась.

Подводя итог, хочу отсортировать arr2 так, когда я l oop через него я получаю значение arr в порядке возрастания (или убывания).

EDIT Я исправляю эту проблему, но появляется другая, когда я применил arr2 к своему html , порядок запутался.

    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 у меня есть некоторый div с классом "triable", и приведенный выше код должен применять стиль (порядок) css, так что div визуально смена позиции

Ответы [ 4 ]

1 голос
/ 05 апреля 2020

Вам нужно вернуть дельту. В противном случае обратный вызов возвращает 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>
0 голосов
/ 05 апреля 2020

функциональная произвольная сортировка

Вот еще один способ решения вашей проблемы. Допустим, у нас есть некоторые fruits и произвольные order мы будем sh для их сортировки -

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

Мы обработаем sh модуль Comparison для обработки нашего кода сортировки -

const { empty, contramap } =
  Comparison

const sortByIndex = (values = [], indexes = []) =>
  contramap(empty, x => indexes.indexOf(values.indexOf(x)))

Теперь нам просто нужно реализовать Comparison -

const Comparison =
  { empty: (a, b) =>
      a < b ? -1
        : a > b ? 1
          : 0
  , contramap: (m, f) =>
      (a, b) => m(f(a), f(b))
  }

const { empty, contramap } =
  Comparison

const sortByIndex = (values = [], indexes = []) =>
  contramap(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 означает, что у нас есть аккуратное место для хранения всех наше сравнение логи c. Мы могли бы легко реализовать другие полезные функции, такие как 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
  }

Теперь мы можем легко смоделировать сложные алгоритмы сортировки c -

const sortByName =
  contramap(empty, x => x.name)

const sortByAge =
  contramap(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, contramap, 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
    ( contramap(empty, x => x.year)  // primary: sort by year
    , contramap(empty, x => x.month) // secondary: sort by month
    , contramap(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
  , contramap: (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, contramap, concat, reverse, nsort } =
  Comparison

const sortByDate =
  nsort
    ( contramap(empty, x => x.year)  // primary
    , contramap(empty, x => x.month) // secondary
    , contramap(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 }
// ]
0 голосов
/ 05 апреля 2020

Код много, но работает:)

Для сортировки AS C:

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);

Для сортировки DES C:

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);
0 голосов
/ 05 апреля 2020

Его гораздо проще, приятель использует этот arr.sort (function (a, b) {return a - b}); // использовать возврат, иначе он не сработает и - + plus обозначает ascndng dcndng ordee Простой метод ..... Счастливое кодирование

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...