@vladymyr_olegovich

Как реализовать сортировку объектов?

Есть "массив" объектов.
var a = {
    q_1: {
        _next: "w_2",
        _prev: "u_7"
    },
    w_2: {
        _next: "e_3",
        _prev: "q_1"
    },
    e_3: {
        _next: "r_4",
        _prev: "w_2"
    },
    r_4: {
        _next: "t_5",
        _prev: "e_3"
    },
    t_5: {
        _next: "y_6",
        _prev: "r_4"
    },
    y_6: {
        _next: "u_7",
        _prev: "t_5"
    },
    u_7: {
        _next: "q_1",
        _prev: "y_6"
    }
}

У каждого элемента есть ключ на предыдущему и следующему элементу. Нужно реализовать сортировку случайным способом, но чтобы можно было вернуться к первоначальному варианту (на подобие сортировки аудиозаписей в VK). Как посоветуете организовать алгоритм?


Я не хочу хранить в памяти еще 1 массив с индексом активного элемента. Плюс к этому у меня в этом объекте есть еще свойства, не относящиеся к элементам, которые нужно сортировать. Я считаю что нужно изменить значения свойств "_next" и "_prev" в самих элементах. Вопрос только как это лучше сделать?
  • Вопрос задан
  • 694 просмотра
Пригласить эксперта
Ответы на вопрос 2
lazalu68
@lazalu68
Salmon
А как вы собираетесь по этим ключам восстанавливать предыдущую сортировку? Вам тогда придется создавать прямо в элементах свойства типа "array_of_previous_next" и т.д., все равно где-то придется хранить информацию о сортировке. Поэтому логичней все-таки отделить сортировку от логики объекта, максимум - задавать объектам либо уникальное имя, либо ID, как-то так:

var array_of_orders = [],
    current_order = 0,
    objects = [
        { name: 'q_1' },
        { name: 'w_2' },
        { name: 'e_3' },
        { name: 'r_4' },
        { name: 't_5' },
        { name: 'y_6' },
        { name: 'u_7' }
    ];

array_of_orders.push( objects.map(function(object) { return object.name; }) );

function sort(sort_function) {
    objects.sort(sort_function || function() { return Math.random() - 0.5; });
    array_of_orders.push( objects.map(function(object) { return object.name; }) );
    current_order = array_of_orders.length - 1;    
}

function applyOrder(index) {
    var order = array_of_orders[index], 
        result, name_to_find, i, k, l;

    if ( order ) {
        l = order.length;
        result = Array( l );

        for (i = 0; i < l; i++) {
            name_to_find = order[i];

            for (k = 0; k < l; k++) {
                if (objects[k].name === name_to_find) {
                    result[i] = objects[k];
                }
            }
        }

        objects = result;
        current_order = index;
    }
};


Все просто: из важных для сортировки свойств object имеет только свойство name, порядок сортировки (массив со значениями свойств name соответствующего объекта) складывается в массив array_of_orders, номер текущего порядка сортировки лежит в переменной current_order. Чтобы отсортировать массив, вызываете функцию sort() с аргументов в виде функции сортировки, ну или без функции, тогда сортировка будет произвольная. Чтобы вернуть предыдущую сортировку, делаете вызов функции applyOrder( current_order - 1 ).
Ответ написан
Комментировать
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
У Вас не массив, а объект, а у объектов произвольный доступ к элементам по их ключу.
Ключи как таковые можно получить в виде массива либо функцией Object.keys, которая получает все нумеруемые ключи объекта включая ключи из цепочки прототипов (к не нумеруемым относятся свойства объявленые через Object.defineProperty за исключением явного указания enumerable: true, а также символы (Symbol) и методы ( { method() { ... } } ) из ES2015), либо функцией Object.getOwnPropertyNames, которая получает все собственные ключи объекта, кроме символов (прототип исключен, enumerable не учитывается)
Случайное перемешивание массива делается элементарно: arr.sort(() => Math.random() - 0.5);

Как итог, можно получить массив ключей Вашего объекта в случайном порядке:
var keys = Object.keys(a).sort(() => Math.random() - 0.5);
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы