Eiffel: есть ли способ с помощью do_all или do_if искать элемент в коллекции без необходимости писать целую функцию?

across
    collection as l_item
until 
    Result /= Void
loop
    if l_item.item.name.is_equal ("foo") then
        Result := l_item.item
    end
end

есть ли способ, и если да, то какой сделать что-то вроде

collection.do_if (agent ...)

пример использования может быть:

search_item_with_id (an_id: INTEGER)
        -- Moves items cursor if not found is_after
    local
        l_found: BOOLEAN
    do
        from
            items.start
        until
            items.after or l_found
        loop
            l_found := items.item.primary_key = an_id
            if not l_found then
                items.forth
            end
        end
    ensure
        cursor_on_element_if_found: not items.after implies items.item.primary_key = an_id
    end

person Pipo    schedule 26.01.2019    source источник
comment
Да, вам просто нужно использовать [Встроенные агенты] (eiffel.org/doc/ eiffel/ET-_Agents#Inline_agents)   -  person javierv    schedule 07.02.2019
comment
@javierv Хорошо, спасибо! но это ответ, а не комментарий! не могли бы вы поставить это или я должен, потому что у вас нет времени?   -  person Pipo    schedule 08.02.2019


Ответы (1)


Да, проверьте следующий пример, где do_all и do_if используются inline agents и подпрограммы, являющиеся частью класса.

Проверьте класс LINEAR в base библиотеке, чтобы узнать больше о других итераторах.

Collection.do_all (action: PROCEDURE [G]): применить action к каждому элементу.

Collection.do_if (action: PROCEDURE [G]; test: FUNCTION [G, BOOLEAN]): применить action к каждому элементу, который удовлетворяет test.

class
    AGENTS_EXAMPLE

create
    make

feature

    make
        do
            print ("%NDo ALL examples: %N")
            example_do_all_with_inline
            example_do_all_with_feature
            print ("%NDo if examples: %N")
            example_do_if_with_inline
            example_do_if_with_features
        end

feature -- Access

    languages: ARRAY [STRING]
            -- Programming languages
        once
            Result := <<"Eiffel", "Ruby", "Python", "C++", "Perl", "Java", "Go", "Rust">>
        end

feature -- Access DO-ALL

    example_do_all_with_inline
            -- with inline
        do
            languages.do_all (agent  (lang: STRING)
                do
                    if lang.same_string_general ("Eiffel") then
                        print ("The OO language with DBC is :) " + lang + "%N")
                    else
                        print ("We don't know what DBC is :( " + lang + "%N")
                    end
                end)
        end

    example_do_all_with_feature
            -- with a feature
        do
            languages.do_all (agent filter_dbc)
        end

    filter_dbc (lang: STRING)
        do
            if lang.same_string_general ("Eiffel") then
                print ("The OO language with DBC is :) " + lang + "%N")
            else
                print ("We don't know what DBC is :( " + lang + "%N")
            end
        end

feature -- Access DO-IF

    example_do_if_with_inline
        do
            languages.do_if (agent  (lang: STRING)
                do
                    print ("The OO language with DBC is :) " + lang + "%N")
                end, agent  (lang: STRING): BOOLEAN
                do
                    if lang.is_case_insensitive_equal ("Eiffel") then
                        Result := True
                    end
                end)
        end

    example_do_if_with_features
        do
            languages.do_if (agent action_print, agent language_dbc_test)
        end

    action_print (a_language: STRING)
        do
            print ("The OO language with DBC is :) " + a_language + "%N")
        end

    language_dbc_test (a_language: STRING): BOOLEAN
        do
            if a_language.is_case_insensitive_equal ("Eiffel") then
                Result := True
            end
        end
end

Чтобы узнать больше о встроенных агентах, ознакомьтесь со следующим руководством.

person javierv    schedule 08.02.2019
comment
Лучшая практика в stackexchange — всегда пытаться ответить на вопрос прямым ответом, даже если вы указываете на какую-то документацию. Я закончу ваш ответ, как только возьму его в свой проект. Спасибо во всех случаях - person Pipo; 08.02.2019