as.list.selenider_elementsR Documentation

Iterate over an element collection

Description

[Experimental]

as.list() transforms a selenider_elements object into a list of selenider_element objects. The result can then be used in for loops and higher order functions like lapply()/purrr::map() (whereas a selenider_element object cannot). This function is stable.

element_list() is the underlying function called by element_list().

Use elem_flatmap() when you want to select further sub-elements for each element of a collection.

elem_flatmap() allows you to apply a function to each element of a selenider_elements object, provided that the function returns a selenider_element/selenider_elements object itself. The result will then be flattened into a single selenider_elements object. The benefit of this over traditional iteration techniques is that the laziness of the elements will be maintained, and nothing will be fetched from the DOM. This function is experimental, and won't work if .f uses elem_flatten() (or nested elem_flatmap()).

elem_flatmap() works by executing .f on a mock element, then recording the results in x. This means that no matter the length of x, .f is only evaluated once, and during the elem_flatmap() call. For this reason, .f should not invoke any side effects or do anything other than selecting sub-elements.

elem_flatmap() can essentially be viewed as a map operation (e.g. lapply(), purrr::map()) followed by a flattening operation (elem_flatmap()). This means that:

x |>
  elem_flatmap(.f)

is essentially equivalent to:

x |>
  as.list() |>
  lapply(.f) |>
  elem_flatten()

However, the second approach is not done lazily.

as.list()/element_list() essentially turns x into: list(x[[1]], x[[2]], ...) However, to do this, the length of x must be computed. This means that while each element inside the list is still lazy, the list itself cannot be considered lazy, since the number of elements in the DOM may change. To avoid problems, it is recommended to use an element list just after it is created, to make sure the list is an accurate representation of the DOM when it is being used.

Usage

## S3 method for class 'selenider_elements'
as.list(x, timeout = NULL, ...)

element_list(x, timeout = NULL)

elem_flatmap(x, .f, ...)

Arguments

x

A selenider_elements object.

timeout

How long to wait for x to exist while computing its length.

...

Passed into .f.

.f

A function to apply to each element of x.

Value

elem_flatmap() returns a selenider_element object. as.list()/element_list() returns a list of selenider_element objects.

See Also

Examples


html <- "
<div id='div1'>
  <p>Text 1</p>
</div>
<div id='div2'>
  <p>Text 2</p>
</div>
<div id='div3'>
  <p>Text 3</p>
</div>
<div id='div4'>
  <p>Text 4</p>
</div>
"

session <- minimal_selenider_session(html)

divs <- ss("div")

# Get the <p> tag inside each div.
divs |>
  elem_flatmap(\(x) x |> find_element("p"))

# Or:
p_tags <- divs |>
  elem_flatmap(find_element, "p")

# To get the text in each tag, we can't use elem_flatmap()
for (elem in as.list(p_tags)) {
  print(elem_text(elem))
}

# Or:
lapply(as.list(p_tags), elem_text)