Reputation: 2961
I am very new to Elixir and Functional Programming.
I am reading a large text file that describes a graph, and need to store it in a Adjacency Matrix and/or Adjacency List for calculations.
I am having a hard problem trying to figure out how to keep storing the values in a data structure , since data is immutable in Functional Programming.
The file is such as this:
3 //Number of Nodes
1 2 //Non-directional edge
3 4
4 2
Q1: How can this be done ? [SOLVED]
Q2: Can this be done with a Stream instead of a full file read ?
Upvotes: 0
Views: 587
Reputation: 222090
There's no one fixed way to parse string into a data structure. For simple cases like this, String.split
and String.to_integer
are good enough. You haven't provided the exact output structure you want so I'll show how to decode this into an integer and a list of pair of integers for the edges.
input = "3
1 2
3 4
4 2"
# or input = File.read!("file.txt")
[head | tail] = String.split(input, "\n")
count = String.to_integer(head)
edges = for line <- tail do
[from, to] = String.split(line)
{String.to_integer(from), String.to_integer(to)}
end
IO.inspect count
IO.inspect edges
Output:
3
[{1, 2}, {3, 4}, {4, 2}]
Upvotes: 1
Reputation: 121000
Another example with a reducer:
(1..10)
|> Enum.to_list # or "file.txt" |> File.read! |> String.split("\n")
|> Enum.reduce(%{}, fn i, acc ->
Map.put acc, <<i + 96 :: utf8>>, i
end)
#⇒ %{
# "a" => 1,
# "b" => 2,
# ...
# "j" => 10
# }
Upvotes: 1
Reputation: 3801
You have pretty much two options in functional languages:
Enum.reduce
)Reduce is really quick and easy if you just need to accumulate a value from a list.
https://hexdocs.pm/elixir/Enum.html#reduce/2
It almost sounds like recursion is the way to go with the problem you're trying to solve:
File.read!("path/to/file.txt")
|> String.split("\n", trim: true)
|> parse(%{})
def parse([line | rest], matrix) do
add_line_to_matrix(line, matrix)
parse(rest, matrix)
end
Upvotes: 1