Q: R Shiny Reactivity, 1 из 2 событий [дубликат]

Что такое лямбда-функция?

Концепция лямбда-функции C ++ основана на исчислении лямбда и функциональном программировании. Лямбда - это неназванная функция, которая полезна (в реальном программировании, а не в теории) для коротких фрагментов кода, которые невозможно повторно использовать и не стоит именовать.

В C ++ функция лямбда определяется следующим образом

[]() { } // barebone lambda

или во всей его славе

[]() mutable -> T { } // T is the return type, still lacking throw()

[] - это список захвата, () список аргументов и {} тело функции.

Список захвата

Список захвата определяет, что из-за лямбда должно быть доступно внутри тела функции и как. Это может быть либо:

  1. значение: [x]
  2. ссылка [& amp; x]
  3. любая переменная, находящаяся в настоящее время в области по ссылке [ & amp;]
  4. то же, что и 3, но по значению [=]

Вы можете смешать любое из вышеперечисленного в списке с разделителями-запятыми [x, &y].

Список аргументов

Список аргументов тот же, что и в любой другой функции C ++.

Тело функции

Код, который будет выполняться, когда на самом деле вызывается лямбда.

Вывод типа возврата

Если лямбда имеет только один оператор return, возвращаемый тип может быть опущен и имеет неявный тип decltype(return_statement).

Mutable

Если лямбда отмечена как изменяемая (например, []() mutable { }), она разрешено изменять значения, которые были записаны по значению.

Случаи использования

Библиотека, определенная стандартом ISO, в значительной степени зависит от лямбда и повышает удобство использования нескольких баров, так как теперь пользователи

C ++ 14

В C ++ 14 lambdas были расширены различными предложениями.

Инициализированные лямбда-захваты

Элемент списка захвата теперь можно инициализировать с помощью =. Это позволяет переименовывать переменные и захватывать, перемещаясь. Пример, взятый из стандарта:

int x = 4;
auto y = [&r = x, x = x+1]()->int {
            r += 2;
            return x+2;
         }();  // Updates ::x to 6, and initializes y to 7.

и один из Википедии, показывающий, как захватить с помощью std::move:

auto ptr = std::make_unique<int>(10); // See below for std::make_unique
auto lambda = [ptr = std::move(ptr)] {return *ptr;};

Generic Lambdas

Теперь Lambdas может быть общим (auto был бы эквивалентен T здесь, если T был аргументом шаблона типа где-то в окружающей области):

auto lambda = [](auto x, auto y) {return x + y;};

Улучшенная вычитание возвращаемого типа

C ++ 14 позволяет выводить возвращаемые типы для каждой функции и не ограничивает ее функциями return expression;. Это также распространяется на лямбда.

37
задан Hillary Sanders 11 January 2016 в 23:32
поделиться

4 ответа

Я знаю, что это старо, но у меня был тот же вопрос. Я наконец-то понял. Вы включаете выражение в фигурные скобки и просто указываете события / реактивные объекты. Моя (необоснованная) догадка заключается в том, что блестящий просто выполняет тот же реактивный анализ указателя на этот блок выражений, что и стандартный блок reactive.

observeEvent({ 
  input$spec_button
  mainplot.click$click
}, { ... } )
50
ответ дан Duncan Brown 15 August 2018 в 19:05
поделиться
  • 1
    Изменение принятого ответа на этот вопрос, поскольку оно кажется лучшим решением, чем мое первоначальное решение. – Hillary Sanders 24 April 2017 в 21:14
  • 2
    Можете ли вы определить, какое событие было вызвано? – PeterVermont 11 May 2017 в 13:20
  • 3
    Не то чтобы я знал. Я делал это в нескольких случаях, отслеживая их в отдельных переменных и сам делал сравнение, чтобы увидеть, что изменилось. Но это уродливо. Вероятно, лучше поставить основной код в функцию, затем иметь два наблюдающих элемента, которые вызывают fn, а затем делать конкретные вещи для каждого события. – Duncan Brown 6 June 2017 в 18:01
  • 4
    Просто предупреждение: observeEvent по умолчанию использует ignoreNULL = TRUE, что означает, что если mainplot.click$click (возвращаемое значение) NULL, обработчик будет никогда не вызываться, даже если input$spec_button изменен. Я бы рекомендовал что-то вроде ответа @ JustAnother, чтобы не попасть в эту ловушку. – greg L 19 February 2018 в 02:52
  • 5
    Еще одно предупреждение: в моем тестировании я обнаружил, что этот синтаксис в скобках ({}) ТРЕБУЕТСЯ, чтобы каждое событие было на собственной новой строке, иначе оно терпит неудачу с ошибкой в ​​анализе ... & quot; как только парсер встретит второе событие. например, все в одной строке: observeEvent({input$spec_button mainplot.click$click}, {...}) терпит неудачу. @ Ответ JustAnother с использованием синтаксиса S3 Generic (c()) работает независимо от новых строк. – Brian D 14 August 2018 в 19:23

Вот решение, с которым я столкнулся: в основном создайте пустой держатель данных reactiveValues, а затем измените его значения на основе двух отдельных экземпляров observeEvent.

  data <- reactiveValues()
  observeEvent(input$spec_button, {
    data$data <- get.focus.spec(input=input, premise=premise, 
                                itemname=input$dropdown.itemname, spec.info=spec.info)
  })
  observeEvent(mainplot.click$click, {
    data$data <- get.focus.spec(input=input, premise=premise, mainplot=mainplot(),
                                mainplot.click_focus=mainplot.click_focus(),
                                spec.info=spec.info)  
  })
5
ответ дан Hillary Sanders 15 August 2018 в 19:05
поделиться
  • 1
    list(mainplot.click$click, input$spec_button) также будет работать для OP. – John 22 September 2016 в 02:51

Также:

observeEvent(c( 
  input$spec_button,
  mainplot.click$click
), { ... } )
21
ответ дан JustAnother 15 August 2018 в 19:05
поделиться
  • 1
    Хотя это выглядит очень похоже на ответ @DuncanBrown, я обнаружил ситуацию, когда две кнопки действий запускают модальный, это сработало, а версия { - нет. Я не могу объяснить, почему это так. – John Paul 10 February 2017 в 17:23
  • 2
    Добавлен комментарий к ответу @Duncan Brown о том, как этот ответ отличается (и лучше ИМО) – greg L 19 February 2018 в 02:54

Я решил эту проблему с созданием реактивного объекта и использовать его в выражении изменения события. Как показано ниже:

xxchange <- reactive({
paste(input$filter , input$term)
})

output$mypotput <- eventReactive( xxchange(), {
...
...
...
} )
3
ответ дан Selcuk Akbas 15 August 2018 в 19:05
поделиться
  • 1
    Это очень хороший ответ, который мог бы получить больше объяснений. Хотя принятый ответ более прямолинейный, что делает его лучше для рудиментарных программ, этот ответ лучше подходит для больших и сложных кодов. В ответе отсутствуют две точки (1) Вставка (или список) помещает два события в одну строку, делая код более компактным. (2) Реактивный объект сохраняет усилия повторения одних и тех же двух событий снова и снова, если более одного слушателя прослушивает один и тот же набор событий. – Agriculturist 12 June 2017 в 19:39
  • 2
    большое и легкое решение !! Спасибо – Digvijay Sawant 18 June 2018 в 17:22
Другие вопросы по тегам:

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