Home > other >  How to continue iteration over a codition even after it has been met once or even multiple times in
How to continue iteration over a codition even after it has been met once or even multiple times in

Time:06-21

I am writing a small package manager in ruby, and while working on its' package searching functionality, I want to continue iterating over a list of matches, even if it has found a package or sting identical to the inputted string.

def makelist(jsn, searchterm)
    len = jsn.length
    n = 0
    while n < len do
      pkname = jsn[n]["Name"]
      pkdesc = jsn[n]["Description"]
      pkver  = jsn[n]["Version"]

      unless pkname != nil || pkdesc != nil
        # skip
      else
        puts "#{fmt(fmt("aur/", 6),0)}#{fmt(pkname,0)} [#{fmt(pkver,8)}]\n    #{pkdesc}"
        n  = 1
      end
    end

  end

I have tried using an if statement, unless statement and a case statement in which I gave conditions for what it should do if it specifically finds a packages that matches searchterm but when I use this condition, it always skips all other conditions and ends the loop, printing only that result. This block of code works, but I want to use my fmt function to format the text of matches differently in the list. Anyone have any ideas of how I could accomplish this?

CodePudding user response:

EDIT: Based on some back and forth the desired behavior is to print matched results differently from unmatched results.

So, in Ruby you have access to "functional" patterns like select, map, reduce, etc. that can be useful for what you're doing here.

It's also advantageous to separate functionality into different methods (e.g. one that searches, one that turns them into a string, one that prints the output). This is just an example of how to break it down, but splitting up the responsibilities makes it much easier to test and see which function isn't doing what you want by examining the intermediate structures.

Also, I'm not sure how you want to "match" the search term, so I used String#include? but you can replace that with whatever matching algorithm you like.

But I think you're looking for something like this:

def makelist(jsn, searchterm)
  jsn.select do |package|
    package["Name"] && package["Description"]
  end.map do |package|
    if matches?(package, searchterm)
      matched_package_to_string(package)
    else
      package_to_string(package)
    end
  end.join("\n")
end
def matches?(package, searchterm)
  package['Name'].include?(searchterm) || package('Description').include?(searchterm)
end
def matched_package_to_string(package)
  pkname = package["Name"]
  pkdesc = package["Description"]
  pkver  = package["Version"]
  "#{fmt(fmt("aur/", 6),0)}#{fmt(pkname,0)} [#{fmt(pkver,8)}]\n    #{pkdesc}"
end
def package_to_string(package)
  # Not sure how these should print
end
  • Related