Почему это не будет работать? Динамический выбор

Хорошо, я делаю это:

Select[Range[1, 20], # > Dynamic[q] &]

И затем создаю слайдер:

Slider[Dynamic[q], {1, 20}]

И он всегда будет возвращать пустой набор! Почему!

Обновление Целью этого является изменение набора при перемещении ползунка.

Ответ 1

Ключ к помните, что Dynamic ничего не контролирует непосредственно в оценке. Он делает это, чтобы создать пятно на экране, которое имеет свойства оценки.

Если, например, вы должны были оценить следующее в новой Mathematica сессия...

b=5;
Dynamic[a=b];
b=6;
Print[a];

... то что будет напечатано? Вместо того, чтобы немедленно оценивать это, подумайте это прежде, чем вы попробуете. Подсказка... это трюк, но понимание трюка откроет ваш разум точно, что делает Dynamic.

Ответ, который я не буду раскрывать здесь (потому что вы действительно должны попробовать его для себя!) можно объяснить тем, что Dynamic никогда ничего не делал потому что он никогда не появлялся на экране. Точка с запятой блокировала экран внешний вид Dynamic и без появления на экране оценки Dynamic ничего не делает.

Более тонко, если вы удалите все точки с запятой, выражение Print [] (at по крайней мере, на моей машине) по-прежнему остается неизменным, но теперь для полного другой причина. Это потому, что экранное размещение динамических гарантий что его содержимое будет оценено, но не тогда, когда они будут оценены. мой пример устанавливает условие гонки, которое, по крайней мере, на моей машине в v7, Shift + Введите оценки выигрышей.

Чтобы вернуться к вашему примеру,

Select[Range[1, 20], # > Dynamic[q] &]

Это не работает так, как вы думаете, потому что Dynamic в этом случае не оценивает то, что отображается на экране.

Вы можете тривиально продемонстрировать результат, выполнив...

Dynamic[Select[Range[1, 20], # > q &]]

но я предполагаю, что вам просто не хотелось показывать его на экране, но в установлении какого-то побочного эффекта. Возможно, вы назначили Select для переменной. Есть два способа сделать эти побочные эффекты. Один из них - положить их в второй аргумент Dynamic. Например...

findset[x_] := (myset = Select[Range[1, 20], # > x &])
Slider[Dynamic[q, (q=#; myset = findset[q])&], {1, 20}]

Второй - создать динамический, который имеет экранный вид, но один что не заметно. Например,

Row[{
    Slider[Dynamic[q], {1, 20}],
    Dynamic[myset = Select[Range[1, 20], # > q &]; ""]
}]

В этом случае отображается динамическое отображение. Он отображается рядом с Slider. Но вы не видите этого, потому что то, что оно отображает, является пустой строкой. Тем не менее, он обладает всеми свойствами автоматического обновления, которые имеет любой динамик.

Для получения дополнительной информации вы должны прочитать начальные и расширенные динамические руководства в документации Mathematica. Вы также можете увидеть мой пост на comp.soft-sys.math.mathematica здесь (который я частично переформулировал для этого ответа).

Ответ 2

Я думаю, вы хотите оставить "Динамический" из выбранного. Кажется, это работает, когда я играю с ним:

In[20]:= x = 5

Out[20]= 5

In[21]:= Slider[Dynamic[x], {1, 20}]

Out[21]= \!\(\*
SliderBox[Dynamic[$CellContext`x], {1, 20}]\)

In[26]:= (*manually move the slider a bit to the right *)

In[23]:= x

Out[23]= 9.36

In[24]:= Select[Range[1, 20], # > x &]

Out[24]= {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}

x = 2 (*slider moves left when I set this*)

Out[25]= 2

РЕДАКТИРОВАТЬ: Ваш фактический вопрос был "почему это не работает", а не "как мне заставить это работать". Здесь проблема:

In[12]:= q = 3

Out[12]= 3


In[13]:= (# > q) &[10]

Out[13]= True


In[14]:= (# > Dynamic[q]) &[10]

(* what you see on the screen looks like an evaluation that is held or something *)
Out[14] = 10 > 3

(* but the full form, which is conveniently what gets copied to the clipboard for
   pasting into this answer, is actually this! *)
Out[14]= 10 > \!\(\*
DynamicBox[ToBoxes[$CellContext`q, StandardForm],
ImageSizeCache->{7., {1., 8.}}]\)

Итак, если вы говорите "Динамический [1]", вы получаете "3" на экране, но это не действительно "3" - это какой-то элемент ноутбука, который фактически отображает "3" .

Результат функции сравнения - это выражение, подобное приведенному выше, которое не оценивается как True, поэтому select не принимает никаких элементов, поэтому вы получаете пустой набор.

Ответ 3

Вы хотите, чтобы целое исходное выражение Select было динамическим, потому что вы хотите обновить выбранное подмножество всякий раз, когда изменяется значение q. Вы можете сделать это, перемещая Dynamic снаружи. Попробуйте следующее:

Slider[Dynamic[q], {1, 20}]

Dynamic[Select[Range[1, 20], # > q &]]