jazzyer
Iterating or Pattern Matching on a certain conditions
I have a pretty straight-forward problem, but struggle to make it clear and concise (is that possible at all!?).
So having two lists:
list_1 = ["$100", "$200", "$300"]
list_2 = ["bob", "$200", "sam"]
success output should be:
"bob: $100, sam: $300"
fail output:
list_1 = ["$100", "$200", "$300"]
list_2 = ["bob", "bob", "sam"]
false
Obviously, list_2 (or our pattern) might be different, but if prices are matching we should return a success output similar to above.
I approached it right away by:
iex(2)> Enum.zip(["bob", "$200", "sam"], ["$100", "$200", "$300"])
[{"bob", "$100"}, {"$200", "$200"}, {"sam", "$300"}]
and then with a lot of conditional logic and accumulators in Enum.reduce solved the problem, but it’s super ugly… When my Elixir code is ugly - I’m always questioning myself, since there is always another and cleaner way.
How would you approach this? Is there a way?
Thank you all in advance!
Marked As Solved
gregvaughn
Format more nicely in production code, but here’s a quick iex solution
iex(91)> list_1 = ["$100", "$200", "$300"]
["$100", "$200", "$300"]
iex(92)> list_2 = ["$100", "tom", "sam"]
["$100", "tom", "sam"]
iex(93)> pairs = Enum.zip(list_1, list_2)
[{"$100", "$100"}, {"$200", "tom"}, {"$300", "sam"}]
iex(94)> if Enum.any?(pairs, &match?({a, a}, &1)), do: Enum.join((for {a, b} <- pairs, a != b, do: "#{b}: #{a}"), ", "), else: false
"tom: $200, sam: $300"
Also Liked
al2o3cr
Based solely on what you’ve posted (I don’t really understand why list_2 has a mix of names and amounts):
list_1 = ["$100", "$200", "$300"]
list_2 = ["bob", "$200", "sam"]
pairs = Enum.zip(list_1, list_2)
unmatched_pairs = Enum.reject(pairs, fn {l1, l2} -> l1 == l2 end)
if length(unmatched_pairs) == length(list_1) do
false
else
unmatched_pairs
|> Enum.map(fn {l1, l2} -> "#{l1}: #{l2}" end)
|> Enum.join(", ")
end
(Edited to fix a bug - was looking at length(pairs) without filtering first)
al2o3cr
Nope, you’re not missing anything - that was a bug! ![]()
The intent is to check the length of the zipped pairs after filtering out ones like {"$200", "$200"} - if none of the pairs got filtered out, we need to return false (a “fail case”).
czrpb
i too dont think i understand the 2 lists, but here is what i have for your 3 tests/examples:
iex(5)> test1 = {["$100", "$200", "$300"], ["bob", "$200", "sam"]}
{["$100", "$200", "$300"], ["bob", "$200", "sam"]}
iex(6)> test2 = {["$100", "$200", "$300"], ["$100", "tom", "sam"]}
{["$100", "$200", "$300"], ["$100", "tom", "sam"]}
iex(7)> test3 = {["$100", "$200", "$300"],["bob", "tom", "sam"]}
{["$100", "$200", "$300"], ["bob", "tom", "sam"]}
iex(8)> [test1, test2, test3] |>
...(8)> Enum.map(fn {list1, list2} ->
...(8)> Enum.zip(list1, list2) |>
...(8)> Enum.reduce({false, []}, fn
...(8)> {l1,l1}, {_, pairs} -> {true, pairs}
...(8)> l1l2, {result, pairs} -> {result, [l1l2|pairs]}
...(8)> end)
...(8)> end)
[
true: [{"$300", "sam"}, {"$100", "bob"}],
true: [{"$300", "sam"}, {"$200", "tom"}],
false: [{"$300", "sam"}, {"$200", "tom"}, {"$100", "bob"}]
]
result/accumulator of the reduce is a tuple: {PASS-FAIL, PAIRS}
jazzyer
@czrpb and @gregvaughn
Thank you so much for your input and sorry about my delay here! That pandemic definitely is not over, got sick finally ![]()
Again, really appreciate it!







