dogweather
My problem
When parsing old government webpages, my input is often just like that one:
<p><b>Section 1, name, and text</b></p>
<p>Section 1 more text</p>
<p>Section 1 more text</p>
<p><b>Section 2, name, and text</b></p>
<p>Section 2 more text</p>
<p><b>Section 3, name, and text</b></p>
// etc.
I’d really like feedback about the approach I came up with last night:
This looks like a take/while/scan kind of problem. But I couldn’t find an Enum or Floki function that seemed to handle this kind of repeated pattern.
I decided to write a function that would generically group items and following items using a predicate. In the case of the HTML above, the predicate would be “Does the element contain a <b>?” So, abstractly:
input = [1,2,2,2,2,1,1,1,2]
output = [[1,2,2,2,2], [1], [1], [1, 2]]
I realized that’s not too hard with Enum.reduce:
def group_after(list, predicate) do
reduce(list, [], fn e, acc ->
case predicate.(e) do
true ->
[[e]] ++ acc
false ->
{curr, rest} = List.pop_at(acc, 0)
[curr ++ [e] | rest]
end
end)
end
It works fine. Although, the reduce function’s code is very procedural and not expressive. What do you all think? Is there another approach I’m not considering?
An alternate idea: Consider a string
"tfffftttf"as an isomorph ofmap(list, predicate). Then use an expressive regex like~r/tf*/to group the true & false — instead of the proceduralreduce. Finally, undo the mapping back into the original list elements.
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #phoenix_html
- #iex
- #graphql
- #ai
- #genstage
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex










First 9 of 9 Posts
Sebb
I’m not sure if I understand correctly. In your real world example the grouping is already done, because
<b>are children of the<p>.But your number example seems to be another problem (chunk by 1s and all 2s that follow a 1)
Eiji
Slow load (possibly timeout). I know what you feel. Hope those are not
ASP.netpages with invalidHTMLcode.Anyway, here is my solution:
Pattern matching is a fastest solution. You can take a look at this post to see possible alternative solutions.
dogweather
Sorry, yeah - I left it abstract. I used the 1’s to represent paragraphs with a
<b>, and 2’s for<p>'s without.Here’s a screenshot of the page.
And I’m trying to produce a list of
%Section{}.The actual HTML looks like this. All of the
<p>'s just run on; there’s no hierarchy. The only clue is that the first line of a Section has a<b>.dogweather
Thanks! That’s pretty interesting. This meta tag is pretty chilling.
It seems they’re somehow scripting MS Word to “Save as HTML”.
Sebb
sounds like fun … not
Eiji
Since you did not give a struct definition I wrote it myself:
What do you think about it?
derek-zhou
This is not too bad; at least all the
<p>have closing</p>. You know they don’t have to; and I;ve seen html that freely mix the 2 styles, with or without closing</p>dogweather
That’s very cool. Thanks for taking a whack at it. The
<span>'s and other attributes aren’t important, though, because they’re the same on every element. (!) The big picture is, we want mostly plain text — simplified HTML. This code’s purpose is to produce well formed JSON with all the important info from the original texts. I publish the JSON to a datasets public repo.You can see how I solved it: The actual
Section:The
group_with/2function:dogweather
I’ll just pray that Floki can handle it. I’m sure I’ll be dealing with that at some point.