0

I have two arrays of strings

order_items=["2832","3284","9832","9234"]
uri=["orderaccept/order_items/3284/cancel","orderaccept/order_items/9234/cancel"]

I want to find all elements of order_items which were not part of uri. In this case, it should return 2832 and 9832.

Feel free to edit the contents of both arrays. I couldn't find a similar question, but if already asked, please link me up.

0

3 Answers 3

2
order_items.select { |item| uri.none? { |u| u.include?(item) } }
Sign up to request clarification or add additional context in comments.

1 Comment

WOW...So cool.The thing that I would have been writing would have at least been a few lines long. (Of course, I am just a newbie to this language. )
2

as a variant:

order_items.select{|i| !uri.join.include? i}

UPDATE

order_items=["2832","3284","9832","9234"]
uri=["orderaccept/order_items/3284/cancel","orderaccept/order_items/9234/cancel"]

require 'benchmark'
joined = uri.join
n = 1_000_000
Benchmark.bm do |x|
  x.report("select:") { n.times do  order_items.select{|i| !uri.join.include? i}; end }
  x.report("reject:") { n.times do  order_items.reject{|i| uri.join.include? i}; end }
  x.report("reject2:") { n.times do  order_items.reject{|i| joined.include? i}; end }
  x.report("none?:") { n.times do  order_items.select { |item| uri.none? { |u| u.include?(item) } }; end }
  x.report("substr:") { n.times do  order_items - uri.map { |e| e.gsub /\D/, '' }; end }
  x.report("subt+substr:") {n.times do order_items - uri.map { |i| i[24..27] }; end }
end

It produced

               user       system      total        real
select:       4.181000   0.015000   4.196000 (  4.275000)
reject:       3.931000   0.000000   3.931000 (  3.925000)
reject2:      1.388000   0.000000   1.388000 (  1.440000)
none?:        4.462000   0.000000   4.462000 (  4.490000)
substr:       26.582000  0.016000   26.598000( 26.675000)
subt+substr:  3.167000   0.000000   3.167000 (  3.170000)

4 Comments

Good idea to use join, but it is not elegant to use select with !. You should rather use reject without !. Also, in order to make your code efficient, you have to do join outside the block. Otherwise, there is no performance benefit, and for expressing the intent directly, Jimmy's answer will be better.
@YevgeniyAnfilofyev I ran benchmarking on subtract as well, I saw an ugly productivity and came to a hack, relying on all strings in uri contain order_items in the fixed position: order_items - uri.map { |i| i[24..27] }. It runs within acceptable timeframes, but still slower than reject2 method (despite the fact it’s absolutely not flexible.)
@mudasobwa just added your last method
Jimmy's answer is much more suitable to my simple needs...But I appreciate the alternative variant. Just shows how many ways something can be done in Ruby.
0

I guess the array subtraction is more applicable here since it’s self-descriptive for future code revisions (you are indeed willing to subtract unnecessary items from an array, aren’t you?)

order_items - uri.map { |e| e.gsub /\D/, '' }

UPD Ooups… Benchmarking forces me to think accurately, for given example it came to:

order_items - uri.map { |i| i[24..27] }

Benchmarking:

order_items=["2832","3284","9832","9234"]
uri=["orderaccept/order_items/3284/cancel","orderaccept/order_items/9234/cancel"]

require 'benchmark'
n = 1_000_000
Benchmark.bm do |x|
  x.report("select:") { n.times do  order_items.select{|i| !uri.join.include? i}; end }
  x.report("reject:") { n.times do  order_items.reject{|i| uri.join.include? i}; end }
  x.report("none?:") { n.times do  order_items.select { |item| uri.none? { |u| u.include?(item) } }; end }
  x.report("subt+gsub:") { n.times do order_items - uri.map { |e| e.gsub /\D/, '' }; end }
  x.report("subt+substr:") {n.times do order_items - uri.map { |i| i[24..27] }; end }
end

Yielding:

       user     system      total        real
select:  7.200000   0.000000   7.200000 (  7.206846)
reject:  6.240000   0.000000   6.240000 (  6.253924)
none?:  9.230000   0.020000   9.250000 (  9.282425)
subt+gsub: 43.440000   0.000000  43.440000 ( 43.491133)
subt+substr:  5.320000   0.010000   5.330000 (  5.333616)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.