#Would like help parsing a data structure (basic)

9 messages · Page 1 of 1 (latest)

stoic zinc
#

I have a data structure (below) and I want to know how to extract the :title and other values from each map. I've experimented using Chat GPT and I still can't figure it out. I assume there is some combination of piplines or pattern matching that makes this easy. I tried stringing together Enum and a pipeline of Map etc and I just make a mess.

data = [ 
  ok: %{    
    description: "HuffPost - United States",
    id: "",
    url: "whatever.com",
    entries: [
      %{
        content: "The former president gave a truly bizarre \"White House\" gift to a visitor.",
        id: "DE33CE1185AC820EB138C4828BD67DFC52BB78C5674885FFB842160753535DD9",
        image: "",
        title: "Dolphin Found Shot Dead On Louisiana Beach With 'Multiple Bullets' In Body",
        updated: ~U[2024-04-25 10:23:48Z],
        url: "https://www.huffpost.com/entry/dolphin-shot-dead-louisiana_n_662a2707e4b01a688b3df1d9"
       },

      %{
        content: "The former president gave a truly bizarre \"White House\" gift to a visitor.",
        id: "DE33CE1185AC820EB138C4828BD67DFC52BB78C5674885FFB842160753535DD9",
        image: "",
        title: "Dolphin Found Shot Dead On Louisiana Beach With 'Multiple Bullets' In Body",
        updated: ~U[2024-04-25 10:23:48Z],
        url: "https://www.huffpost.com/entry/dolphin-shot-dead-louisiana_n_662a2707e4b01a688b3df1d9"
      }
    ]
  },
  ok: %{    
     # same as above -  (about 50 more entries)
  } 
]


stoic zinc
#

I cobbled the below code together but I'm sure there is something more concise. ```elixir

def run(value) do
[
"https://www.cbsnews.com/latest/rss/main",
"https://abcnews.go.com/abcnews/usheadlines",
"http://rss.cnn.com/rss/cnn_topstories.rss",
"https://chaski.huffpost.com/us/auto/vertical/us-news"
]
|> Enum.map(fn rssItem -> ElixirRss.fetch_and_parse(rssItem) end)
|> parse_rss_list(value)

end

def parse_rss_list(data, query_key) do
items = for {_, map} <- data, entry <- map, do: entry

Enum.each(items, fn {key, value} ->
  if key == query_key  do
    IO.inspect(value)
    value
  end
end)

end

halcyon hull
#

you could do something like this:


def parse_rss_list(data, key) do
  for {:ok, map} <- data, entries <- map[:entries] || [], {^key, value} <- entries, do: value
end
#

where key is an atom representing a key in entry

stoic zinc
#

@halcyon hull When you think of parsing through complicated data structures like this do you generally let your mind drift toward using the "for" comprehension first? Using "Enum" methods was my first thought and I figured there was some pattern match thing that I could do that I didn't know about. I'm just trying to learn how to "think" about data like this in Elixir. In JavaScript this would be much easier for me.

unborn plover
#

something like:

Enum.flat_map(data, fn {:ok, %{entries: entries} when is_list(entries) -> 
   Enum.map(entries, &Map.get(&1, key))
  _ -> 
    []
end)

You can also make the comprehension a little shorter

for {:ok, %{entries: [ _ | _] = entries} <- data,
    {^key, value} <- entries do 
  value
end
#

i think in this instance, the comprehension is nicer to read

halcyon hull