Removing Items from list

Hello all,

I’m playing with nhs API, and after fetching the data and doing some clean up I’m a bit stuck on how to remove items from the list.

I’m doing everything from the iex shell so the code goes something like this

nhs_endpoint = "https://api.nhs.uk/conditions/pregnancy-and-baby/"
headers = [{"subscription-key", "key"}]

%{status_code: 200, body: body, request_url: request_url} = HTTPoison.get!(nhs_endpoint, headers)
%{"url" => url, "author" => author, "dateModified" => date_created, "description" => title, "mainEntityOfPage" => page, "relatedLink" => link} = Poison.decode!(body)

# Go trough the map of map and map URL into list
l = Enum.flat_map(link, fn %{"relatedLink" => relatedLink} -> relatedLink end)
Enum.flat_map(l, fn %{"relatedLink" => relatedLink} -> relatedLink |> Enum.map(fn %{"url" => url} -> url end) end)

It will basically boil don’t to this list of URLs

["https://api.nhs.uk/conditions/coronavirus-covid-19-old2/people-at-higher-risk-from-coronavirus/pregnancy-and-coronavirus/",
 "https://api.nhs.uk/conditions/pregnancy-and-baby/due-date-calculator/",
 "https://api.nhs.uk/conditions/pregnancy-and-baby/when-pregnancy-goes-wrong/",
 "https://www.nhs.uk/start4life/signups/new",
 "https://api.nhs.uk/conditions/pregnancy-and-baby/healthy-pregnancy-diet/",
 "https://api.nhs.uk/conditions/pregnancy-and-baby/planning-pregnancy/",
 "https://api.nhs.uk/conditions/pregnancy-and-baby/foods-to-avoid-pregnant/",
...]

this is a shorter version of the result, but as you see I have an imposter starting with https://www.nhs.uk/* which I want to remove, so what is a proper way of removing these items?

Hi,
try Enum.reject/2 with the correct predicate.

Hey @smita sure, I was trying something like this

m |> Enum.reject(fn %{"url" => url} -> url === "https://www.nhs.uk/*" end) |> Enum.map(fn %{"url" => url} -> url end)

and m is a flat map of

%{
    "@type" => "LinkRole",
    "linkRelationship" => "Navigation",
    "name" => "Where to give birth: your options",
    "position" => 0,
    "url" => "https://api.nhs.uk/conditions/pregnancy-and-baby/where-can-i-give-birth/"
  },
  %{
    "@type" => "LinkRole",
    "linkRelationship" => "Navigation",
    "name" => "Antenatal classes",
    "position" => 1,
    ...
  },

but that did not work, I assume I’m not using the correct predicate.

Try this:

Enum.reject(arr, &String.starts_with?(&1, "https://www.nhs.uk"))

which is the same as

Enum.reject(arr, fn url ->
  String.starts_with?(url, "https://www.nhs.uk")
end)
3 Likes

The === operator make strict match, there is no wildcard here. You should use String.starts_with?/2 with second parameter https://www.nhs.uk.

4 Likes

@stefanluptak thanks, I was reading about String.starts_with? but somehow misunderstood it, thanks for the example, and clarification.

1 Like

Have you considered using Enum.filter/2 and pattern matching?

filtered_list =
   list 
   |> Enum.filter(&filter_fun/1)

def filter_fun("https://www.nhs.uk" <> _rest) do
   false
end

def filter_fun(_valid) do
   true
end