人生就是不斷學習,調整與更新持續前進。

Ruby 設計一個萬用的函式v1

工作日常中,突然想設計一個靈活的 Ruby 函式 universal_function,有需要的時候可以應用。

它具有以下特點:

  1. 無參數調用時返回 nil
  2. 單一參數時有不同的處理邏輯:
    • 字串:反轉
    • 數字:加倍
    • 數組:隨機排序
    • Hash:轉換 key 為字串
  3. 多參數支持:
    • 兩個數字相加
    • 兩個 Hash 合併
    • 兩個數組組合成 Hash
  4. 三個數字求和
  5. 支持關鍵字參數過濾和轉換
  6. 支持區塊操作,可以對輸入進行變換

 

實際程式:




def universal_function(*args, **kwargs, &block)
  # 處理不同類型的輸入和場景
  
  # 1. 如果沒有參數,返回 nil
  return nil if args.empty? && kwargs.empty? && !block_given?
  
  # 2. 如果只有一個參數,執行基本處理
  if args.length == 1 && kwargs.empty? && !block_given?
    case args.first
    when String
      return args.first.reverse  
    when Numeric
      return args.first * 2      
    when Array
      return args.first.shuffle  
    when Hash
      return args.first.transform_keys(&:to_s) 
    else
      return args.first          
    end
  end
  
  # 3. 處理多個參數的情況
  if args.any?
    case args.length
    when 2
      return args.first + args.last if args.all? { |arg| arg.is_a?(Numeric) }
      return args.first.merge(args.last) if args.all? { |arg| arg.is_a?(Hash) }
      return args.first.zip(args.last).to_h if args.all? { |arg| arg.is_a?(Array) }
    when 3
      return args.sum if args.all? { |arg| arg.is_a?(Numeric) }
    end
  end
  
  # 4. 處理關鍵字參數
  if kwargs.any?
    case 
    when kwargs.key?(:filter)
      return args.first.select { |item| kwargs[:filter].call(item) } if args.first.is_a?(Array)
    when kwargs.key?(:transform)
      return args.first.map { |item| kwargs[:transform].call(item) } if args.first.is_a?(Array)
    end
  end
  
  # 5. 處理區塊
  if block_given?
    return args.map(&block) if args.any?
    return kwargs.transform_values(&block) if kwargs.any?
  end
  
  # 6. 最後的備用返回
  args.any? ? args : kwargs
end

# 示範使用
puts universal_function(5)                              # 輸出: 10
puts universal_function("hello")                        # 輸出: olleh
puts universal_function([1, 2, 3])                      # 輸出: 隨機排序的數組
puts universal_function({a: 1, b: 2})                   # 輸出: {"a"=>1, "b"=>2}
puts universal_function(1, 2)                           # 輸出: 3
puts universal_function([1, 2, 3], filter: ->(x) { x.even? })  # 輸出: [2]
puts universal_function([1, 2, 3]) { |x| x * 2 }        # 輸出: [2, 4, 6]