SearchItems

Страницы: 1 2 След.
RSS
SearchItems
 
Пытаюсь постичь глубокий смысл этой функции. Но, что-то не получается.
Примеры, приведенные в руководстве, содержат функции обратного вызова с

Код
function fn(t)
if t.qty == 103 then
или
Код
function fn(par1, par2, par3)
if par1 == 103 and par2 == “SPBFUT” and par3 == “RIM3” then

Это что же, для каждой конкретной выборки свою функцию писать !?

Хотелось бы иметь универсальную fn, а набор контролируемых параметров и их значения  задавать при вызове SearchItems.

В принципе, я написал такую функцию, function SearchTables(tables,s,e,fn,...). Работает с переменным списком аргументов, а универсальная fn(t,...) выбирает таблицы, удовлетворяющие ВСЕМ условиям, например:

Код
st =  SearchTables("trades",0,getNumberOf("trades")-1,fn,"price",119.35,"qty",10)
Но она использует getItem(), а как я понимаю,  именно из-за слишком медленной ее работы и была создана SearchItems ...
 
Цитата
Андрей 77 написал:
Пытаюсь постичь глубокий смысл этой функции. Но, что-то не получается.

Глубокий смысл в том чтобы быстро получить номера строк удовлетворяющие требованиям.

Цитата
Андрей 77 написал:
Это что же, для каждой конкретной выборки свою функцию писать !?
Зачем? Никто не мешает в fn передавать какие нибудь параметры.

Цитата
Андрей 77 написал:
Хотелось бы иметь универсальную fn, а набор контролируемых параметров и их значения  задавать при вызове SearchItems.

Никто не мешает задавать набор  контролируемых параметров в функции SearchItems

Цитата
Андрей 77 написал:
Но она использует getItem(),

SearchItems выдает таблицу которая содержит номера нужных строк, который в любом случае нужно передавать в getItem.

Цитата
Андрей 77 написал:
а как я понимаю,  именно из-за слишком медленной ее работы и была создана SearchItems ...
Неверно понимаете, getItem в любом случае придется использовать.
SearchItems создавался чтобы избежать лишних циклов.
 
если работаете с колбеками,
то эта функция нужна лишь при запуске скрипта для выборки того,
что уже принято, если оно Вам надо.
----------------------------
А при запуске скорости особо и не надо.
------------------------
Поэтому нет особой разницы каким образом выбрать уже принятые данные .
 
"Никто не мешает в fn передавать какие нибудь параметры."

Дело даже не в значениях параметров. В приведенных примерах fn - принципиально различные функции. Одна принимает таблицу и проверяет один конкретный параметр,
другая получает и проверяет три параметра.

Например, вот такая универсальная функция получает произвольное число параметров (пар имя, значение) и проверяет то, что ВСЕ они для заданной таблицы удовлетворены.
Код
function fn(t,...)
    local arg = {...}
    for k,v in ipairs(arg) do
        if k % 2 == 1 then
            key = v
        else
            val = v
            if t[key] ~= val then
                return false
            end
        end
    end
    return true
end 
 
универсальное медленнее специального.
------------------
Вам что надо?  Быстро или универсально (т е лень писать код) ?
-----------------------------------
 
В данном случае замедления не будет, а удобство налицо - fn один раз приводится для любых проверок/выборок с любым набором параметров. А раз все равно getItem используется, то такой подход дает максимальное удобство при сохранении скорости. Конечно, если понадобится другой тип выборки (например qty > 1 and qty < 10) то придется отдельную функцию писать.
 
Собственно функция не плохая.
Но как уже заметил,
надобности в ускорении выбора из таблиц при работе с колбеками не возникает.
 
С колбеками вообще нет надобности лазить в хранилище.
 
Цитата
Андрей 77 написал:
В данном случае замедления не будет, а удобство налицо - fn один раз приводится для любых проверок/выборок с любым набором параметров. А раз все равно getItem используется, то такой подход дает максимальное удобство при сохранении скорости. Конечно, если понадобится другой тип выборки (например qty > 1 and qty < 10) то придется отдельную функцию писать.
Добрый день.
А не могли бы Вы привести законченный пример с использованием этой универсальной функции поиска?
 
Да, конечно.
Код
--
-- SearshTables
--


--
-- Универсальная функция обратного вызова для SearchTables. 
-- Реализует проверку условий для переменного набора параметров 
-- Возвращает true если удовлетворены ВСЕ условия (AND), иначе - false
-- 

function fn(t,...)

    local arg = {...}

    for k,v in ipairs(arg) do

        if k % 2 == 1 then
            key = v
        else
            val = v
            if t[key] ~= val then
                return false
            end

        end

    end

    return true

end 


--
-- Функция поиска элементов (таблиц) удовлетворяющих набору критериев. 
-- Переменное число параметров и соответствующих значенией, например :
-- 
-- SearchTables("trades",0,getNumberOf("trades")-1,fn,"seccode","SBER","qty",1,"price",120)
--
-- Возвращает таблицу, сожержащую сделки (таблицы) по SBER с qty=1 И price=120.


function SearchTables(tables,s,e,fn,...)

local f = {},k
local arg = {...}

    k = 0
    for n = s,e do

        local t = getItem(tables,n)

        if fn(t,...) then  
            k = k+1
            table.insert(f,k,t)
        end

    end

        return f
end


--
-- Пример использования SearchTables
--

function main()


    st =  SearchTables("trades",0,getNumberOf("trades")-1,fn,"seccode","SRM6","price",12138,"qty",1)

    message("Found trades: "..#st,1)


end
 
Разумеется, достаточно возвращать номера таблиц(сделок), поэтому можно вместо table.insert(f,k,t) написать
Код
table.insert(f,k,n)
 
Основные затраты при поиске перебором используя getItem это передача структур данных из хост-программы через стек в скрипт. SearchItems дает возможность уменьшить эти расходы.
Используя Ваш пример я написал похожую реализацию с помощью функции SearchItems. Исходный код я немного модифицировал для подсчета статистики.
Исходный пример
Пример реализации с SearchItems
Результаты тестов на моей машине:
 
Это все замечательно, но не меняет того странного обстоятельства, что вызов функции SearchItems не предполагает передачу значений параметров. Вместо написания конкретной функции fn для каждой выборки вы предлагаете использовать громоздкую новую функцию, вся задача которой - передавать значения параметров в SearchItems.

Проблема в самой реализации SearchItems. Очевидно, все определяется тем, как SearchItems вызывает fn. Нельзя ли дополнить ее таким образом, чтобы можно было передавать параметры и их значения в самой SearchItems ? Либо в виде последовательности параметров и значений (как в моем примере) либо в виде единой строки "par1=val1,par2=val2".
 
Цитата
Michael Bulychev написал:
Основные затраты при поиске перебором используя getItem это передача структур данных из хост-программы через стек в скрипт. SearchItems дает возможность уменьшить эти расходы.
Используя Ваш пример я написал похожую реализацию с помощью функции SearchItems. Исходный код я немного модифицировал для подсчета статистики.
Исходный пример
Пример реализации с SearchItems
Результаты тестов на моей машине:
Добрый день, Михаил
Просьба протестите еще  SearchItems без всех этих приблуд.
Просто для конкретного варианта.
Сколько будет по сравнению с этими выкрутасами.
Спасибо
------------------------------------------------
Универсальная система (программа) - это такая система(программа) ,
разработчики которой не имеют ни малейшего представления о том,
как реально ее будут применять.
 
Никакой разницы не будет. Ибо всю работу выполняет SearchItems. Все остальное просто сервис подготовки fn.
 
Еще один вариант. Суть та же, но чуть попроще, чем у Михаила (я минималист :)). По сути - одна дополнительная универсальная функция, 17 строк. Работает так же, даже чуть быстрее (на 2%), правда у меня ПК в 4 раза медленнее, чем у Михаила :(
Код
-- SelectItems
-- Возвращает таблицу с номерами элементов в 'tables', удовлетворяющих 
-- набору критериев вида p = { par1=val1, par2=val2, ... }
-- s - start, e - end
--

function SelectItems(tables,s,e,p)

local t,fields={},""

    for key,val in pairs(p) do
        fields = fields .. "," .. tostring(key)                    
        t[#t+1] = val
    end

local function fn(...)

local args = {...}
    for key,val in ipairs(args) do
        if t[key] ~= val then
            return false
        end
    end
    return true
end
    return SearchItems(tables,s,e,fn,fields)
end


-- ---------------------------------------------------------------------
-- Пример использования SelectItems
-- ---------------------------------------------------------------------

function main()

local table,n,N,params

    table = "all_trades"
    n = getNumberOf(table)-1
    params = {sec_code='RIM6',class_code='SPBFUT',qty=1}

    N = 100
    
    message("Selecting from "..table.." ("..n..") "..N.." times")
    _start = os.clock()

    for i = 1, N do
        st = SelectItems(table,0,n,params)
    end

    _end = os.clock()

    time = _end - _start
    message("Found: "..#st..",time: "..string.format("%.1f",time),1)

end



.
 
Добрый день,
Считаю, что возврат только номеров найденных строк не совсем удачное решение.
После этого надо еще вытаскивать эти строки из хранилища.
--------------------------------
Предлагаю возвращать таблицу номеров и таблицу самих строк,
в которых возвращать лишь параметры,
которые не участвовали в поиске.
Спасибо
 
или ,
как вариант,
задавать список возвращаемых параметров для найденных строк
 
например,
надо найти все активные стоп-заявки, чтобы их удалить.
Указываем , что вернуть надо order_num,  а ищем по flags.
В результате получаем таблицу номеров активных стоп-заявок.
 
Добрый день.
Вы можете прямо в теле функции сохранять нужную вам информацию и всегда возвращать false.
 
Цитата
Michael Bulychev написал:
Добрый день.
Вы можете прямо в теле функции сохранять нужную вам информацию и всегда возвращать false.
но тогда какой смысл в возврате функцией таблицы номеров строк?
Если следовать Вашей логике, то можно все сохранять в теле функции.
И вообще все писать от печки.
 
Это просто вариант решения Вашей задачи - использовать SearchItems как итератор по данным.
 
Цитата
Sergey Gorokhov написал:
Никто не мешает задавать набор  контролируемых параметров в функции SearchItems
Непонятно. Приведите пример.
 
Цитата
Ирина написал:
Цитата
Sergey Gorokhov   написал:
Никто не мешает задавать набор  контролируемых параметров в функции SearchItems
Непонятно. Приведите пример.

В функции SearchItems последним параметром Вы задаете список параметров которые следует смотреть в функции fn.
Пример есть в документации QLUA.chm:
Код
function fn(par1, par2, par3)
    if par1 ==  103 and par2 == "SPBFUT" and par3 == "RIM3" then
        return true    
else
        return false    
   end
end
t1 = SearchItems("all_trades", 0, getNumberOf("all_trades")-1, fn, [B]"qty,class_code, sec_code"[/B])

 
Поправка, предыдущий пример содержит лишние символы.
Вот правильный:
Код
   function   fn (par1, par2, par3)
     if  par1  =  =    103   and  par2  =  =   "SPBFUT"   and  par3  =  =   "RIM3"   then 
         return   true     
 else 
         return   false     
    end 
 end 
t1  =   SearchItems ( "all_trades" ,  0 ,  getNumberOf ( "all_trades" ) -  1 , fn, "qty,class_code, sec_code")

  
 
Sergey Gorokhov, документацию видела. Выше шла речь о неудобстве постоянного прописывания дополнительной функции fn:
Цитата
Sergey Gorokhov написал:

ЦитатаАндрей 77 написал:
Хотелось бы иметь универсальную fn, а набор контролируемых параметров и их значения  задавать при вызове SearchItems.

Никто не мешает задавать набор  контролируемых параметров в функции SearchItems
Значения контролируемых параметров или условия "фильтрации" этих значений в самой функции SearchItems как задать?
 
Цитата
Ирина написал:
Значения контролируемых параметров или условия "фильтрации" этих значений в самой функции SearchItems как задать?

Если правильно понимаем, Вы не хотите создавать отдельную функцию?
Если так пропишите ее внутри тела функции SearchItems
пример так:
Код
t1 = SearchItems ("all_trades",0,getNumberOf ("all_trades")-1, function(par1, par2, par3) if (par1 == 103) and (par2 == "SPBFUT") and (par3 == "RIM3") then  return true else return false end end , "qty,class_code, sec_code")
 
Sergey Gorokhov, прикольно! Не думала, что в Lua так можно. Подозреваю, времени обработки "функция в функции" не убавит. А букв меньше не стало.
Цитата
Sergey Gorokhov написал:
Если правильно понимаем, Вы не хотите создавать отдельную функцию?
Да, правильно поняли, спасибо за пример. Но хотелось бы записи в виде таблицы с параметрами что ли, как в функции sendTransaction.
 
Цитата
Ирина написал:
Но хотелось бы записи в виде таблицы с параметрами что ли, как в функции sendTransaction.

согласно документации, если последний параметр в функции SearchItems не задан то в функцию передается таблица со всеми параметрами.
пример
Код
t1 = SearchItems ("all_trades",0,getNumberOf ("all_trades")-1, function(T) if (T.qty == 103) and (T.class_code== "SPBFUT") and (T.sec_code== "RIM3") then  return true else return false end end)
 
Цитата
Sergey Gorokhov написал:
если последний параметр в функции SearchItems не задан
так он задан. Вопрос в способе присвоения ему значений.
Так
Код
t1 = SearchItems ("all_trades",0,getNumberOf ("all_trades")-1, {["qty"] =103, ["class_code"]="SPBFUT", ["sec_code"]= "RIM3"})
можно? Понятно, что нет. Что-нить похожее можно изобразить?
 
Цитата
Ирина написал:
Что-нить похожее можно изобразить?
Нет нельзя.
Используйте предложенный вариант. Суть та же самая.
 
Цитата
Sergey Gorokhov написал:
Нет нельзя.
Используйте предложенный вариант. Суть та же самая.
Хорошо. :sad:
 
Если SearchItems не найдет ни одного элемента, удовлетворяющего условиям поиска, что вернет? Nil, пустую таблицу?
 
Цитата
Ирина написал:
Если SearchItems не найдет ни одного элемента, удовлетворяющего условиям поиска, что вернет? Nil, пустую таблицу?
Добрый день, если будет ошибка, то вернется Nil, если ничего не найдет, то пусто.
 
Индекс конечного элемента, заданный переменной или функцией, вычисляется 1 раз перед поиском, или его изменение во время работы SearchItems будет учтено? Например, в SearchItems("all_trades", 0, getNumberOf("all_trades")-1, fn).

Откуда можно узнать, как индексируется таблица, возвращаемая SearchItems?
 
И ещё. Последовательность перебора элементов от стартового до конечного соблюдается или в хаотичном порядке?
 
Цитата
Ирина написал:
Индекс конечного элемента, заданный переменной или функцией, вычисляется 1 раз перед поиском, или его изменение во время работы SearchItems будет учтено?
Один раз перед поиском.
Цитата
Ирина написал:
Откуда можно узнать, как индексируется таблица, возвращаемая SearchItems?
Данные индексируются ровно в том порядке как поступили с биржи.

Цитата
Ирина написал:
И ещё. Последовательность перебора элементов от стартового до конечного соблюдается или в хаотичном порядке?
Да, хронология соблюдается.
 
Sergey Gorokhov, спасибо.

Цитата
Sergey Gorokhov написал:
Данные индексируются ровно в том порядке как поступили с биржи.
Это Вы о расположении найденных элементов, видимо.
Я интересуюсь, как индексируется таблица, созданная SearchItems? Нагуглила уже, что числами, начиная с 1. Но где это указано?
 
Цитата
Ирина написал:
Я интересуюсь, как индексируется таблица, созданная SearchItems? Нагуглила уже, что числами, начиная с 1. Но где это указано?
Не понятно какого ответа Вы ожидаете.
Есть официальная документация QLUA.chm. Если в ней нет ответа, значит надо спросить
 
Цитата
Sergey Gorokhov написал:
Не понятно какого ответа Вы ожидаете.
Ну раз уж не ссылки на документацию, то хотя бы подтверждения, может, нюансов каких-то, т.к. информацию я нашла в неофициальном источнике... Но Ваш ответ лучше - смешнее!  :lol:  
 
Если я не ошибаюсь, раньше SearchItems ("all_trades",0,getNumberOf ("all_trades")-1)
обрабатывал строки с "0" до последней.
Сейчас только одну. Может я чего не так делаю?
 
Цитата
Серега написал:
Если я не ошибаюсь, раньше SearchItems ("all_trades",0,getNumberOf ("all_trades")-1) обрабатывал строки с "0" до последней.
У Вас в функции не хватает параметров, в частности функции обратного вызова.
 
Цитата
Sergey Gorokhov написал:
Цитата
Серега написал:
Если я не ошибаюсь, раньше SearchItems ("all_trades",0,getNumberOf ("all_trades")-1) обрабатывал строки с "0" до последней.
У Вас в функции не хватает параметров, в частности функции обратного вызова.
Да, это понятно.
Для примера:
Код
function fn(seccode,flags,qty)
   if seccode=="SiH9" then
      message ( tostring(qty) ) -- выдает только строку =0, а должен все строки
      message ( tostring(flags) )
      message ( tostring(seccode) ) 
   end
end

function main()
   SearchItems("orders", 0, getNumberOf("orders")-1, fn, "sec_code,flags,qty")
end


Да, в любом коде, берет только первую строку. (Напишите свой пример, чтобы долго не придираться. А то сейчас растянем)
А раньше брал с 0 строки по последнюю строку в таблице.
Те LUA, которые раньше с SearchItems работали, теперь обрабатывают этой функцией только первую заданную ("0" нулевую) строку.
QUIK 7.24.1.15
 
Серега,
Согласно документации:

Цитата

fn – функция обратного вызова, возвращающая одно из следующих значений:
true – текущий индекс учитывается в результате;
false – текущий индекс не учитывается в результате;
nil – поиск прерывается, функция SearchItems возвращает таблицу с индексами, найденными ранее, включая текущий индекс.

у Вас в коде, функция fn ничего не возвращает, т.е. по сути это nil, поэтому поиск и прекращается.
Добавьте return true и поиск будет происходить по полному циклу
 
Вот теперь работает. Спасибо!
 
Парни, подскажите пожалуйста!
Как через SearchItems, можно запомнить первую активную заявку в таблице "orders".
И в следующий раз начинать с этой строки?

SearchItems (с 0 по end) в 5й строке активная заявка
SearchItems (с 5 по end) в 10й строке активная заявка
SearchItems (с 10 по end)
 
Серега,
Просто запомнить номер строки и в следующий раз указать его в SearchItems.
не понятно в чем сложность
 
Цитата
Sergey Gorokhov написал:
Просто запомнить номер строки и в следующий раз указать его в SearchItems.
не понятно в чем сложность

Тоже не понимаю в чем, но сложность остается. ))

Код
function fn(flags,order_num)
i=i+1
   if bit.band(flags, 1)==1 then
   message ( "активна "..tostring(i).."  "..tostring(order_num))
   -- return i
   end
return true
end 

function main()
   is_run,i = true,0
   while is_run do
   SearchItems("orders", i, getNumberOf("orders")-1, fn, "flags,order_num")
   message ( "последняя "..tostring( i ))
   sleep(2000)
   end
end

function OnStop(s)
is_run = false
end


Как запомнить строку с первой активной заявкой ?
 
Цитата
Серега написал:
Как запомнить строку с первой активной заявкой ?

1) записать order_num в глобальную переменную
2) записать в файл
3) записать в базу
4) записать в таблицу
и т.п.
 
Цитата
Sergey Gorokhov написал:
Цитата
Серега написал:
Как запомнить строку с первой активной заявкой ?
1) записать order_num в глобальную переменную
2) записать в файл
3) записать в базу
4) записать в таблицу
и т.п.

Поправка, надо не так. В fn не передается номер строки.
Надо при нахождении нужной заявки делать return nil
далее последняя запись в таблице которую возвращает SearchItems надо смотреть последнюю строку, она и будет содержать нужный номер строки
Страницы: 1 2 След.
Читают тему
Наверх