Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Как добавить элемент в отсортированный массив? (https://javascript.ru/forum/misc/84813-kak-dobavit-ehlement-v-otsortirovannyjj-massiv.html)

webgraph 06.01.2023 16:02

Цитата:

Сообщение от voraa (Сообщение 549737)
Следующий найти будет трудно, если мы изъяли какие то после текущего.
Придется в цикле ключи перебирать.
И как взять первый? Перебрать все и найти минимальный?

Для перебора коллекции Map есть 3 метода:

map.keys() – возвращает итерируемый объект по ключам,
map.values() – возвращает итерируемый объект по значениям,
map.entries() – возвращает итерируемый объект по парам вида [ключ, значение], этот вариант используется по умолчанию в for..of.

let recipeMap = new Map([
  ["огурец", 500],
  ["помидор", 350],
  ["лук",    50]
]);

// перебор по ключам (овощи)
for (let vegetable of recipeMap.keys()) {
  alert(vegetable); // огурец, помидор, лук
}

// перебор по значениям (числа)
for (let amount of recipeMap.values()) {
  alert(amount); // 500, 350, 50
}

// перебор по элементам в формате [ключ, значение]
for (let entry of recipeMap) { // то же самое, что и recipeMap.entries()
  alert(entry); // огурец,500 (и так далее)
}


А зачем их искать, если массив по итогу каждый раз перебирается от начала до конца?

voraa 06.01.2023 16:03

Вся реализация со списком Не отлаживал, конечно, но как то так
class CPoolItem {
    next = null;
    prev = null;
    operation;

    constructor (operation) {
        this.operation = operation;
    }
}

class CPool {
    first = null;
    last = null;
    constructor () {}

    // добавить в конец
    add (item) {
        this.fist ??= item;
        item.prev = this.last;
        if (this.last) 
            this.last.next = item;
        this.last = item;
        return this;
    }

    // удалить item
    delete (item) {
        const next = item.next;
        const prev = item.prev;
        if (!prev)
            this.first = next;
        else 
            prev.next = next;
        if (!next)
            this.last = prev;
        else
            next.prev = prev;
        return this;
    }
    // последовательно просмотреть pool, выполняя операции, какие возможно.
    view () {
        let item = this.first;
        while (item) {
            if (canExec(item.operation)) {
                exec (item.operation);
                this.delete(item)
            }
            item = item.next
        }
    }
}

const pool = new CPool();

// Когда поcтупила новая операция делаем
poll.add(new CPoolItem(operation));
pool.view();

// Когда какая то операция выполнилась удаляем участников из буфера и делаем
pool.view();

// canExec(operation) проверяет, что участников операции нет в буфере
// exec (operation) добавляет участников в буфер и отправляет операцию на исполнение.

webgraph 06.01.2023 16:16

Цитата:

Сообщение от voraa (Сообщение 549739)
Вся реализация со списком Не отлаживал, конечно, но как то так

Что-то здесь вообще ничего не понятно...

webgraph 06.01.2023 16:25

Цитата:

Сообщение от voraa
реализация со списком

С каким списком?) Я не понимаю во что именно добавляется. Это массив, объект, мап?)

voraa 06.01.2023 16:29

Простая работа с двунаправленным списком.
operation - некий объект, который мне точно не известен, но он описывает операцию, которую надо выполнить. От кого, кому, что ....
operation оборачивается в CPoolItem. Это айтем нашего пула.
new CPoolItem(operation)
Сам пул задается классом CPool.
в нем определены методы add - добавление айтема в конец пула,
delete - удаления айтема из пула
и view последовательный просмотр пула с выполнением операций, которые на данный момент возможны.

voraa 06.01.2023 16:37

Ну список это обычная структура данных.
Есть всякие очереди, деревья, списки...
В них элементы располагаются не последовательно, как в массиве, а где угодно, но связаны между собой указателями.
В двунаправленных списках у каждого элемента есть указатели на предыдущий элемент (prev) и следующий (next).
В самом заголовке списка есть указатели на первый (first) и последний (last)
Обычный список

webgraph 06.01.2023 16:59

Цитата:

Сообщение от voraa (Сообщение 549743)
Ну список это обычная структура данных.
Есть всякие очереди, деревья, списки...
В них элементы располагаются не последовательно, как в массиве, а где угодно, но связаны между собой указателями.
В двунаправленных списках у каждого элемента есть указатели на предыдущий элемент (prev) и следующий (next).
В самом заголовке списка есть указатели на первый (first) и последний (last)
Обычный список

А в чем конкретно преимущество этого списка по сравнению с тем же Map?) Как этот список экспортировать и импортировать?

voraa 06.01.2023 18:02

Ну если только такой перебор с инкрементным ключом, то наверно и Map подойдет.

Alexandroppolus 06.01.2023 20:15

Цитата:

Сообщение от webgraph
В 99% случаев для каждого участника операции будет свободное место в buffer. А если и не будет - то оно очень скоро освободится.

Т.е. почти всегда очередь будет пустая?

Это хорошо, но могут возникать какие-либо тормоза в обработке запросов. В этом случае в очереди накопится много элементов. Если длина очереди равна N, то разгребать её надо будет за время примерно N*N/2 (просмотр всей очереди после завершения каждой операции). И это может стать проблемой.

voraa 06.01.2023 20:24

Я тесты провел.
Просмотр очереди из 100_000 записей с удалением половины (все четные, например) занимает 15-40 мс даже на моем довольно старом AMD
Я сравнивал свою реализацию со списком и реализацию через map.
Результаты разнятся от теста к тесту. То список чуть быстрее, то map.


Часовой пояс GMT +3, время: 18:45.