38 Returning a List of Vectors
TipObjective
Work with an iterator of tuples and turn each into a small character vector.
The query string of a url is a set of key=value pairs. In https://example.com/?a=1&b=2 the pairs are a=1 and b=2. We want to pull these out for each url.
query_pairs() returns tuples
The query_pairs() method gives an iterator of tuples. Each tuple is a (key, value) where both are string-like. We covered tuples this morning. We access the parts by position, or destructure them in a closure.
For each pair we build a two element character vector c(key, value). Each url then becomes a list of those pairs, and the whole thing is a list of lists.
The key and value come back as a Cow<str>, which is a borrowed-or-owned string. We call .to_string() on each to get an owned String we can hand to R.
Exercise
- Write
url_query_pairs(url: List) -> List - For each url, get the pointer with
get_extptr - Map over
query_pairs(), destructuring each tuple as(key, value) - Build a
Stringsofc(key, value)for each pair - Collect each url’s pairs into a
List - A failed pointer returns
NULL
View solution
#[extendr]
fn url_query_pairs(url: List) -> List {
url.into_iter()
.map(|(_, robj)| match RUrl::get_extptr(robj) {
Ok(rurl) => rurl
.0
.query_pairs()
.map(|(key, value)| {
Strings::from_values([
Rstr::from(key.to_string()),
Rstr::from(value.to_string()),
])
.into_robj()
})
.collect::<List>()
.into_robj(),
Err(_) => ().into_robj(),
})
.collect()
}