fork download
  1. $VERBOSE = true
  2.  
  3. class Array
  4. private
  5.  
  6. def _uniq_by(&block)
  7. new, memo = [], {}
  8.  
  9. map(&block).each_with_index do |mapped, idx|
  10. unless memo[mapped]
  11. memo[mapped] = true
  12. new << self[idx]
  13. end
  14. end
  15.  
  16. new
  17. end
  18.  
  19. alias_method :_uniq, :uniq
  20. alias_method :_uniq!, :uniq!
  21.  
  22. public
  23.  
  24. def uniq(&block)
  25. block_given? ? _uniq_by(&block) : _uniq
  26. end
  27.  
  28. def uniq!(&block)
  29. if block_given?
  30. new = _uniq_by(&block)
  31.  
  32. if self == new
  33. nil
  34. else
  35. replace(new)
  36. end
  37. else
  38. _uniq!
  39. end
  40. end
  41. end
  42.  
  43. valid_table = [
  44. [1,"eric", 23, "seattle"],
  45. [1,"eric", 23, "chicago"]
  46. ]
  47.  
  48. invalid_table = [
  49. [1,"eric", 23, "seattle"],
  50. [2,"eric", 45, "seattle"]
  51. ]
  52.  
  53. puts '# uniq'
  54. p valid_table.uniq
  55. p valid_table.uniq{|l|[l[1], l[3]]}
  56. p valid_table.uniq!{|l|[l[1], l[3]]}
  57. p valid_table
  58. p valid_table.uniq!{|l|[l[1], l[3]]}
  59. p valid_table
  60.  
  61. puts '# uniq!'
  62. p invalid_table.uniq
  63. p invalid_table.uniq{|l|[l[1], l[3]]}
  64. p invalid_table.uniq!{|l|[l[1], l[3]]}
  65. p invalid_table
  66. p invalid_table.uniq!{|l|[l[1], l[3]]}
  67. p invalid_table
Success #stdin #stdout 0s 4760KB
stdin
Standard input is empty
stdout
# uniq
[[1, "eric", 23, "seattle"], [1, "eric", 23, "chicago"]]
[[1, "eric", 23, "seattle"], [1, "eric", 23, "chicago"]]
nil
[[1, "eric", 23, "seattle"], [1, "eric", 23, "chicago"]]
nil
[[1, "eric", 23, "seattle"], [1, "eric", 23, "chicago"]]
# uniq!
[[1, "eric", 23, "seattle"], [2, "eric", 45, "seattle"]]
[[1, "eric", 23, "seattle"]]
[[1, "eric", 23, "seattle"]]
[[1, "eric", 23, "seattle"]]
nil
[[1, "eric", 23, "seattle"]]