How to remove duplicate case‑insensitive words separated by multiple delimiters from a string in Ruby

1 Answer

0 votes
require "set"

#
# Remove duplicate case‑insensitive words separated by multiple delimiters.
#
# Features:
# - Case‑insensitive comparison (String#downcase)
# - Preserves original casing of the first occurrence
# - Trims whitespace around tokens
# - Supports ANY number of delimiters (including multi‑character)
# - Preserves original order
# - Efficient O(n) lookup using Set
#

# ---------------------------------------------------------------
# Build a regex that matches ANY delimiter
# ---------------------------------------------------------------
def build_delimiter_regex(delimiters)
  # Escape delimiters so characters like "|" or "*" are treated literally
  escaped = delimiters.map { |d| Regexp.escape(d) }

  # Combine into one regex: (delim1|delim2|...)
  Regexp.new("(?:#{escaped.join('|')})+")
end

# ---------------------------------------------------------------
# Split input string using multiple delimiters
# ---------------------------------------------------------------
def split_by_delimiters(input, delimiters)
  regex = build_delimiter_regex(delimiters)

  input
    .split(regex)
    .map(&:strip)
    .reject(&:empty?)
end

# ---------------------------------------------------------------
# Remove duplicates (case‑insensitive)
# ---------------------------------------------------------------
def remove_duplicates_case_insensitive(tokens)
  seen = Set.new
  unique = []

  tokens.each do |token|
    key = token.downcase
    unless seen.include?(key)
      seen.add(key)
      unique << token
    end
  end

  unique
end

# ---------------------------------------------------------------
# Join tokens with a chosen delimiter
# ---------------------------------------------------------------
def join_tokens(tokens, delimiter)
  tokens.join(delimiter)
end

# ---------------------------------------------------------------
# Main function
# ---------------------------------------------------------------
def remove_duplicates_multi_delimiter_ci(input, delimiters, output_delimiter)
  tokens = split_by_delimiters(input, delimiters)
  unique = remove_duplicates_case_insensitive(tokens)
  join_tokens(unique, output_delimiter)
end

# ---------------------------------------------------------------
# Main
# ---------------------------------------------------------------

s = "AAA | aaa ,   aAA * aaA | AAa | AAA   | BBB | ccc ---- CCC | AAA ; aaa | bbb"
delimiters = ["  ", "|", ",", "*", "-", ";"]

result = remove_duplicates_multi_delimiter_ci(s, delimiters, " | ")
puts result



=begin
run:

AAA | BBB | ccc

=end

 



answered Aug 2 by avibootz

Related questions

...