Function Repository Resource:

SelectByCurrentValue

Source Notebook

Efficiently select from a list of front end objects

Contributed by: Richard Hennigan (Wolfram Research)

ResourceFunction["SelectByCurrentValue"][{obj1,obj2,},key]

gives a list of the obji where CurrentValue[obji,key] would yield True.

ResourceFunction["SelectByCurrentValue"][{obj1,obj2,},key,func]

gives a list of the obji where func[CurrentValue[obji,key]] would yield True.

Details and Options

The obji can be any mix of the following:
NotebookObject[]a currently open notebook
CellObject[]a cell in an open notebook
BoxObject[]a particular box in a cell
$FrontEndSessionan object representing settings for the current front end session
$FrontEndan object representing global settings for the front end
When using the option setting AbsoluteTrue, ResourceFunction["SelectByCurrentValue"] will use AbsoluteCurrentValue instead of CurrentValue.

Examples

Basic Examples (3) 

Select all the evaluatable cells in the current notebook:

In[1]:=
ResourceFunction["SelectByCurrentValue"][Cells[], Evaluatable] // Short
Out[1]=

Find cells with a large font size:

In[2]:=
ResourceFunction["SelectByCurrentValue"][Cells[], FontSize, GreaterThan[20]]
Out[2]=

Get only the notebooks that are currently visible:

In[3]:=
notebooks = Notebooks[]
Out[3]=
In[4]:=
ResourceFunction["SelectByCurrentValue"][notebooks, Visible]
Out[4]=

Scope (3) 

Lists can be used to specify nested values:

In[5]:=
ResourceFunction["SelectByCurrentValue"][Cells[], {CellMargins, 1, 1},
  LessThan[50]]
Out[5]=

Select notebooks by values of TaggingRules:

In[6]:=
CreateWindow[TaggingRules -> {"MyData" -> {"MyTag" -> True}}, WindowTitle -> "SelectMe"]
Out[6]=
In[7]:=
ResourceFunction["SelectByCurrentValue"][
 Notebooks[], {TaggingRules, "MyData", "MyTag"}]
Out[7]=
In[8]:=
NotebookClose /@ %;

The given list can contain a mixture of front end object types:

In[9]:=
{Dynamic[box1 = EvaluationBox[]], Dynamic[box2 = EvaluationBox[], Background -> Green], Dynamic[cell = EvaluationCell[]], Dynamic[nb = EvaluationNotebook[]]}
Out[9]=
In[10]:=
ResourceFunction[
 "SelectByCurrentValue"][{box1, box2, cell, nb}, Background, ColorQ]
Out[10]=
In[11]:=
NotebookRead[%]
Out[11]=

Options (2) 

Absolute (2) 

CurrentValue reports some values as Automatic:

In[12]:=
ResourceFunction["SelectByCurrentValue"][
 Notebooks[], WindowTitle, # === "Messages" &]
Out[12]=
In[13]:=
CurrentValue[Notebooks[], WindowTitle]
Out[13]=

Set AbsoluteTrue to use AbsoluteCurrentValue instead:

In[14]:=
ResourceFunction["SelectByCurrentValue"][
 Notebooks[], WindowTitle, # === "Messages" &, Absolute -> True]
Out[14]=
In[15]:=
AbsoluteCurrentValue[Notebooks[], WindowTitle]
Out[15]=

Applications (2) 

Find cells in the current notebook that have been modified in the past 60 seconds:

In[16]:=
now = AbsoluteTime[TimeZone -> 0];
ResourceFunction["SelectByCurrentValue"][Cells[], CellChangeTimes, now - Max[#] < 60 &]
Out[15]=

View the contents of the cells:

In[17]:=
Framed@*RawBoxes /@ NotebookRead[%]
Out[17]=

Properties and Relations (1) 

SelectByCurrentValue is typically much faster than using Select with CurrentValue:

In[18]:=
nbo = CreateDocument[
  Table[ExpressionCell[i, TaggingRules -> {"tag" -> i}], {i, 1000}]]
Out[18]=
In[19]:=
Select[Cells[nbo], PrimeQ[CurrentValue[#, {TaggingRules, "tag"}]] &] //
   Length // RepeatedTiming
Out[19]=
In[20]:=
ResourceFunction["SelectByCurrentValue"][
   Cells[nbo], {TaggingRules, "tag"}, PrimeQ] // Length // RepeatedTiming
Out[20]=
In[21]:=
NotebookClose[nbo]

Possible Issues (1) 

Some objects inherit values from their parent object, even when not a valid option for that object type:

In[22]:=
ResourceFunction[
 "SelectByCurrentValue"][{EvaluationCell[], EvaluationNotebook[]}, {WindowSize, 1}, NumberQ]
Out[22]=
In[23]:=
CurrentValue[EvaluationCell[], WindowSize]
Out[23]=
In[24]:=
Options[Cell, WindowSize]
Out[24]=

Neat Examples (3) 

Save the corresponding BoxObject for each Dynamic expression in a list:

In[25]:=
bagOfBoxes = ResourceFunction["ExpressionBag"][{}, "Boxes"]
Out[25]=
In[26]:=
Table[Dynamic[Framed[Length[Append[bagOfBoxes, EvaluationBox[]]]], SingleEvaluation -> True, Background -> RandomColor[]], 100]
Out[26]=

Get the boxes:

In[27]:=
Short[boxes = Get[bagOfBoxes]]
Out[27]=

Enlarge the green ones:

In[28]:=
greenishBoxes = ResourceFunction["SelectByCurrentValue"][boxes, Background, ColorDistance[#, Green] < .5 &]
Out[28]=
In[29]:=
CurrentValue[greenishBoxes, FontSize] = 30;

Create a dynamic search filter for a notebook:

In[30]:=
applyFilter[notebook_, ""] := CurrentValue[Cells[notebook], CellOpen] = True;

applyFilter[notebook_, search_] :=
  Module[{cells, show},
   cells = Cells[notebook];
   show = ResourceFunction["SelectByCurrentValue"][
     cells, {TaggingRules, "FilterWord"}, Or @@ StringStartsQ[#1, search, IgnoreCase -> True] &];
   CurrentValue[show, CellOpen] = True;
   CurrentValue[Complement[cells, show], CellOpen] = False;
   ];
In[31]:=
words = Take[WordList[], 100];
In[32]:=
word = "";
searchBox = InputField[Dynamic[word, applyFilter[notebook, word = #1] &], String,
   ContinuousAction -> True, FieldHint -> "Filter"]
Out[29]=
In[33]:=
notebook = CreateDocument[(ExpressionCell[
      Row[{"Filter word: ", Style[#1, Bold]}], "DockedCell", TaggingRules -> {"FilterWord" -> #1}] &) /@ words, WindowTitle -> "Searchable Notebook", DockedCells -> {Cell[
     BoxData[ToBoxes[Row[{"Search: " , searchBox}]]]]}]
Out[33]=

Do a brute-force search for boxes that have a specific property:

In[34]:=
ResourceFunction["BirdSay"][
 Row[{"Try to find this: ", Dynamic[Framed["box"], BaseStyle -> "BirdStyle"]}]]
Out[34]=
In[35]:=
Rasterize[Dynamic[newBox = EvaluationBox[]]];
id = First[newBox]
Out[31]=
In[36]:=
ResourceFunction["SelectByCurrentValue"][
 BoxObject /@ Range[2 id], BaseStyle, #1 === "BirdStyle" &]
Out[36]=
In[37]:=
ResourceFunction["BirdSay"][
 Row[{"Found it: ", RawBoxes[NotebookRead[First[%]]]}]]
Out[37]=

Version History

  • 1.0.1 – 14 March 2022
  • 1.0.0 – 11 May 2020

Related Resources

License Information