Check by name if an item exists

● ARCHIVED · READ-ONLY
Started by Yin 9 posts View original ↗
  1. How do I check by name if an item exists in the database and then return the ID of the item? 

    This is in RGSS3.
  2. perhaps you can explain what you're planning to do.


    All database names are set pre-gaming, so checking for name and returning an ID is not neccessary because you can look up the ID in the editor. Such a command is simply not needed with the default database


    If you're using a dynamic database script and item instances created during gameplay, then the answer depends on what script you're using, so we need a link to that script.
  3. I'm using Tsukihime's Custom Database to generate the items mid game with a crafting script. But if the item exists already, I just want it to reference the item that's already created rather than adding duplicates.

    The script I'm using to generate the objects:

    http://www.himeworks.com/2013/01/26/custom-database/ 

    EDIT: I think I got it. I used a for loop to sift through the database items. Don't know how efficient this is, but I think it might work out. If I have any more questions about this, I will be back here.

    Code:
              id = 1          for i in $data_items            check = $data_items[id]p           check.name            if check.name == i.name              modid = id              break            end            id += 1          end
  4. This also allows you to search for partial names or use regular expressions for finding items. Note that this will return the ID of the first item that is found, and items are searched in order. Returns nil if no item was found with the given argument.

    Code:
    def find_first(name)  $data_items.compact.select { |i| i.name[name] }.first.idrescue  nilend
  5. Thank you! I was just starting to have problems with my code. This works! 

    Can you explain to me what it's doing here i.name[name]?

    It works, but I would like to understand what I'm reading too, so I can use it again in the future.
  6. I'm interested in that rescue clause. Is that so that you can conveniently just reference the id on your selected array, and if it can't find the id property/method it rescues and returns nil?
  7. Yin said:
    Can you explain to me what it's doing here i.name[name]?
    Sure. Basically, I just used the "index" method on String the same way that you'd use it on an Array -- the side effect of this is that it essentially searches the string for the given contents and returns the substring if those contents are found (or nil if the given contents don't exist). The most interesting thing about this, to me, is that it works just as well with substrings as it does with regular expressions.

    The i.name portion simply returns the name of an individual item. Considering this was used in a block passed to select, we're essentially scanning each item in the database and filtering them based on the name given by searching each one's name for the given substring.

    BadMinotaur said:
    I'm interested in that rescue clause. Is that so that you can conveniently just reference the id on your selected array, and if it can't find the id property/method it rescues and returns nil?
    Pretty much. It's also in case an exception occurs at any step along the way -- but it will only rescue exceptions which are descendants of StandardError, so if something really interesting happens, we'll still have something raised.

    Also, I took that opportunity to show people that method definitions are implicit begin ... end blocks because, well, that's good to know. Essentially, the method could have just as easily been written like this and behaved the same way:

    Code:
    def find_first(name)  $data_items.compact.select { |i| i.name[name] }.first.id rescue nilend# This works, too, but it's terribly verbose.def find_first(name)  begin    $data_items.compact.select { |i| i.name[name] }.first.id  rescue    nil  endend
  8. If you only want the first result, you can use Enumerable#find instead of #select AKA #find_all.

    Code:
    def find_first(name)  (result = $data_items.compact.find { |i| i.name[name] }) && result.idend
    Or the “long” version, that does the same, but probably is easier to understand:
    Code:
    def find_first(name)  result = $data_items.compact.find { |i| i.name[name] }  result.id if resultend
  9. Honestly, I completely forgot about the Enumerable#find method -- that is the better choice, both in terms of execution speed and semantics.