Сортировка и фильтрация таблиц QUIK средствами Lua

Страницы: 1
RSS
Сортировка и фильтрация таблиц QUIK средствами Lua
 
Задача: выудить из таблицы стоп-заявок активную стоп-заявку определенной направленности и вида с минимальной стоп-ценой.
Вопрос: Можно ли командами из скрипта отфильтровать таблицу, чтобы исключить заявки с посторонними флагами, видами и др. параметрами, и отсортировать, чтобы интересующая заявка получила заведомо известный индекс 0 или getNumberOf-1 ?
 
Цитата
Ирина написал:
Вопрос: Можно ли командами из скрипта отфильтровать таблицу, чтобы исключить заявки с посторонними флагами, видами и др. параметрами
Можно сначала через SearchItems найти все элементы таблицы по нужным параметрам, и потом получить их через getItem и сохранить в свою таблицу.
Цитата
Ирина написал:
и отсортировать, чтобы интересующая заявка получила заведомо известный индекс 0 или getNumberOf-1 ?
...и потом эту свою таблицу отсортировать через table.sort уже по требуемому параметру, например цене.
 
Suntor, с фильтрацией согласна. Но тянуть каждый getItem-ом... Сколько времени уйдет на сотню заявок?
table.sort сама б не нашла, спасибо.
 
Цитата
Ирина написал:
Suntor  , с фильтрацией согласна. Но тянуть каждый getItem-ом... Сколько времени уйдет на сотню заявок?
table.sort сама б не нашла, спасибо.
А без getItem сами элементы не получите, SearchItems возвращает таблицу только с индексами этих элементов... таков порядок работы этих ф-ций... 100 заявок это мало. Уйдут миллисекунды на современных ПК разумеется... ))) Ну вы можете конечно в саму ф-цию fn для SearchItems сразу в тело встроить сохранение найденных элементов куда вам надо.

Да и вообще, то что вы описали можно сделать без всяких сортировок в одном цикле прохода по таблице стоп-заявок. Ну типа такого:
Поиск стоп-заявки на продажу с минимальной стоп-ценой:
Код
local condition_price = nil
local min_stop_order = nil
for i=0,getNumberOf("stop_orders")-1 do
    local stop_order = getItem("stop_orders", i)
    if stop_order and stop_order.condition == 4 then
        condition_price = condition_price or stop_order.condition_price
        min_stop_order = min_stop_order or stop_order
        if condition_price > stop_order.condition_price then
            condition_price = stop_order.condition_price
            min_stop_order = stop_order
        end
    end
end
— код написал от руки, прямо сюда, не проверяя... доработайте его напильником, перепроверьте... но суть думаю понятна.
 
Даже ещё проще:
Код
local min_stop_order = nil
for i=0,getNumberOf("stop_orders")-1 do
    local stop_order = getItem("stop_orders", i)
    if stop_order and stop_order.condition == 4 then
        min_stop_order = min_stop_order or stop_order
        min_stop_order = (min_stop_order.condition_price <= stop_order.condition_price) and min_stop_order or stop_order
    end
end
 
Цитата
Suntor написал:
Да и вообще, то что вы описали можно сделать без всяких сортировок в одном цикле прохода по таблице стоп-заявок. Ну типа такого:
Здорово! Для моих целей - за глаза! Спасибо большое!

Вот тут
Код
min_stop_order = min_stop_order or stop_order
min_stop_order = (min_stop_order.condition_price <= stop_order.condition_price) and min_stop_order or stop_order
зациклился мой мозг минут на 15 на первой итерации, а на второй ушел на больничный... Если знак не перепутан (ищем мы минимум), поясните, пожалуйста.

Таблицу min_stop_order Вы не объявляете фигурными скобками, потому как она автоматом перенимает тип stop_order или это с nil связано?

Из спортивного интереса, SearchItems тут сэкономит миллисекунду? Вроде того:
Код
function fn(par)
    if par==4 then
        return true
    else
        return false
    end
end
local i = SearchItems("stop_orders", 0, getNumberOf("stop_orders")-1, fn, "condition")

local min_stop_order = nil
for i=0, #i-1 do
    local stop_order = getItem("stop_orders", i)
    min_stop_order = min_stop_order or stop_order
    min_stop_order = (min_stop_order.condition_price <= stop_order.condition_price) and min_stop_order or stop_order
end
 
И ещё вопросик по:
Цитата
Suntor написал:        
Код
min_stop_order = min_stop_order or stop_order
min_stop_order = (min_stop_order.condition_price <= stop_order.condition_price) and min_stop_order or stop_order
Логическая операция первой строки полностью присутствует во второй. Зачем она, первая строка?
 
Цитата
Вот тут
Код
min_stop_order = min_stop_order or stop_order
min_stop_order = (min_stop_order.condition_price <= stop_order.condition_price) and min_stop_order or stop_order
зациклился мой мозг минут на 15 на первой итерации, а на второй ушел на больничный... Если знак не перепутан (ищем мы минимум), поясните, пожалуйста.
Полезные идиомы Lua с использованием and и or.
Знак не перепутан. Ищем мин. из двух чисел.  
 
Цитата
Вот тут

Код


min_stop_order = min_stop_order or stop_order
min_stop_order = (min_stop_order.condition_price <= stop_order.condition_price) and min_stop_order or stop_order

зациклился мой мозг минут на 15 на первой итерации, а на второй ушел на больничный... Если знак не перепутан (ищем мы минимум), поясните, пожалуйста.

Полезные идиомы Lua с использованием and и or.
Знак не перепутан. Ищем мин. из двух чисел.
 
Игорь Б, При первом проходе присваивается значение stop_order (т.к. min_stop_order = nil). При втором, если в stop_order нужное нам меньшее значение, оставляется первое min_stop_order.condition_price (неравенство в скобках - истина, min_stop_order - истина, соответственно, "and" берет min_stop_order, а "or" на нем же и останавливается). Где я ошибаюсь?
 
Цитата
Цитата
И ещё вопросик по:
Цитата
Suntor   написал:  
Код
min_stop_order = min_stop_order or stop_order
min_stop_order = (min_stop_order.condition_price <= stop_order.condition_price) and min_stop_order or stop_order
Логическая операция первой строки полностью присутствует во второй. Зачем она, первая строка?
В первой строке "or" вернет min_stop_order , если это истина.
Во второй сначала вычисляется "and", и только потом "результат and" or stop_order. Т.е. первую строку нельзя сравнивать с куском второй.
 
Я то же самое написала выше.
Цитата
Игорь Б написал:
Во второй сначала вычисляется "and"
И таким образом, при сравнении истин, новое минимальное значение никогда не будет присвоено.
 
т.е. "and" всегда будет возвращать предыдущий min_stop_order, а "or" его подхватывать.
 
Цитата
Игорь Б написал:
Т.е. первую строку нельзя сравнивать с куском второй.
вот это вообще непонятно, Вы о чем?
 
Цитата
т.е. "and" всегда будет возвращать предыдущий min_stop_order, а "or" его подхватывать.
Нет. т.к. в скобках может быть как истина так и ложь.
 
Игорь Б, не заметила сразу, что это
Цитата
Игорь Б написал:
Т.е. первую строку нельзя сравнивать с куском второй.
Вы на другой мой чайниковский вопрос отвечали... Но всё равно непонятно. Не надо первую строку ни с чем сравнивать. Её надо убрать. Само сравнение есть во второй.
 
Цитата
Игорь Б написал:
Нет. т.к. в скобках может быть как истина так и ложь.
речь только об истине (когда наткнулись на нужное значение).
 
Если в скобках ложь. "and"  вернет ложь.   "or" будет сравнивать ложь и  stop_order вернет stop_order .
Если в скобках истина . "and"  вернет min_stop_order .   "or" будет сравнивать min_stop_order  и  stop_order. Вернет min_stop_order (т.к.min_stop_order - истина).
 
Ну и глюк у меня случился!!! Конечно, знак не перепутан, это у меня глаза min_stop_order.condition_price и stop_order.condition_price местами перепутали! Мозг-то на больничном.
Извините!
Игорь Б, спасибо за попытки объяснить!
 
Цитата
Игорь Б написал:
Если в скобках ложь. "and"  вернет ложь.   "or" будет сравнивать ложь и  stop_order вернет stop_order .
Если в скобках истина . "and"  вернет min_stop_order .   "or" будет сравнивать min_stop_order  и  stop_order. Вернет min_stop_order (т.к.min_stop_order - истина).
Да, да, всё верно излагаете. Я так и читала, только с личным глюком. Респект за терпение!  
 
Удачи
 
Думается мне, что наличие первой строки объясняется какими-то особенностями сравнения с nil?  
 
Цитата
Ирина написал:
Код
min_stop_order = min_stop_order or stop_order
min_stop_order = (min_stop_order.condition_price <= stop_order.condition_price) and min_stop_order or stop_order  
зациклился мой мозг минут на 15 на первой итерации, а на второй ушел на больничный... Если знак не перепутан (ищем мы минимум), поясните, пожалуйста.
Первая строчка — это типовой шаблон-паттерн первичной инициализации переменной с nil значением:x = x or V
Если x == nil вначале, то ей будет присвоено значение V, а если x ~= nil, то она будет присвоена сама себе и сохранит значение.

В моём примере первая строчка нужна, чтобы не было ошибки во второй. Так как во второй строчке идёт обращение к элементу .condition_price переменной min_stop_order, и если эта переменная равна nil при первом проходе, то просто произойдёт ошибка обращение к элементу nil таблицы, то-есть (nil).condition_price

Сама вторая строчка, такой же стандартный шаблон-паттерн присвоения по условию: x = (exp) and A or B
Если exp == true, то x = A, иначе x = B.

Цитата
Ирина написал:
Из спортивного интереса, SearchItems тут сэкономит миллисекунду? Вроде того:
Код
   function   fn (par)
     if  par =  =  4   then 
         return   true 
     else 
         return   false 
     end 
 end 
 local  i  =   SearchItems ( "stop_orders" ,  0 ,  getNumberOf ( "stop_orders" ) -  1 , fn,  "condition" )

 local  min_stop_order  =   nil 
 for  i =  0 ,  # i -  1   do 
     local  stop_order  =   getItem ( "stop_orders" , i)
    min_stop_order  =  min_stop_order  or  stop_order
    min_stop_order  =  (min_stop_order.condition_price  <  =  stop_order.condition_price)  and  min_stop_order  or  stop_order
 end 
  
Наоборот, перебор такой же по времени, но при этом написали лишний код, усложнили, добавили выделением памяти под таблицу индексов и пр...
К тому же, у вас там ряд ошибок. Переменной i обозначили как саму таблицу индексов, так и сам индекс. А также убрали одну из проверок на возврат getItem значения nil, что лучше не делать, даже если вы уверены, что по индексам вам не должно вернуться nil. Это просто неправильный стиль программирования. Проверки на ошибки должны присутствовать всегда.

P.S. Смотрю, с утра были бурные обсуждения пары строчек кода... )))
 
Suntor, гран мерси за четкие и исчерпывающие объяснения!!!  
Страницы: 1
Читают тему
Наверх