Skip to content

Instantly share code, notes, and snippets.

@brettwise
Last active December 8, 2015 05:09
Show Gist options
  • Save brettwise/8a3714cc3c3e92ba3867 to your computer and use it in GitHub Desktop.
Save brettwise/8a3714cc3c3e92ba3867 to your computer and use it in GitHub Desktop.
finder.exs
defmodule Finder do
@doc """
`run` takes a word or phrase via the `search_term` argument and passes it to `find'. But primarily `run` returns a list of files from a specified directory and passes it to the `find` function.
"""
def run(directory_path, search_term) do
[head|tail] = File.ls!(directory_path)
find([head|tail], 0, directory_path, search_term)
end
@doc """
`find` returns to the command line how many times and in which files the `search_term` occurs. It takes 4 arguments. The first is a list, the list of files to search through which is passed in by run. The second is an accumulator that keeps track of how many files have been searched. The third is the search term initially passed into `run`.
"""
def find([head|tail], files_searched, directory_path, search_term) do
if tail == [] do
IO.puts "Complete! Searched #{files_searched} files in total."
else
file = File.read!(directory_path <> "/" <> head)
outcome = String.contains?(file, search_term)
case outcome do
true ->
IO.puts "Found term in: #{head}."
# Splits on the search term and tests the length of the array - 1 because the number of terms is always going to be one less than the length of the array.
occurences = length(String.split(file, search_term)) - 1
IO.puts "Term occured #{occurences} time/s." # Did it this way because I thought it was more readable.
find(tail, files_searched + 1, directory_path, search_term)
false ->
find(tail, files_searched + 1, directory_path, search_term)
end
end
end
end
@brettwise
Copy link
Author

The idea here is to search a directory of text files for the search term provided.

Example: Finder.run("100-txt-files", "cat")

@keathley
Copy link

keathley commented Dec 8, 2015

The first thing that I would do is split out the if tail == [] into its own def find clause and just match it explicitly. In general you really want each function to just do 1 small thing.

Prefer string interpolation over concatenation: "#{directory_path}/#{head}" vs. directory_path <> "/" <> head.

Since you're going to call find at the end of your function anyway I would tend to use if String.contains?(file, search_term) here instead of the case. Its only going to return a boolean value and you don't need to worry about the false case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment