1
\$\begingroup\$

So my question is the cleanest way to do #product_panels_for below:

class ProductPanel < Struct.new(:product)
end
class ProductPresenter
 def product_panels_for(selected_products)
 selected_products.map do |product|
 product_panels.find { |panel| panel.product.to_s == product }
 end.
 compact
 end
 def product_panels
 [ProductPanel.new(:iphone), ProductPanel.new(:ipad), ProductPanel.new(:ibidet)]
 end
end
ProductPresenter.new.product_panels_for(['ipad', 'iphone']) # => [<ProductPanel product=:ipad>, <ProductPanel product=:iphone>]

This is obviously simplified, but the point is #product_panels_for should return values from product_panels but in the order given in selected_panels. Maybe this is fine is just feels a bit gangly for something that seems conceptually simpler than that.

To be clear the order is defined by the business, it won't be alphabetical or anything nice.

In case anyone's thinking it, yes, I know in Ruby 2.7 I could replace .map...compact with .filter_map, but I'm not on 2.7 yet.

My previous implementation was:

def product_panels_for(selected_products)
 product_panels.select { |pp| selected_products.include?(pp) }
end

which was nice and clean but didn't preserve the order of selected_products.

If the implementation at the top can't be improved on, is there a nice way to use this previous implementation but chain something after the select that sorts the result so the order matches selected_products? I'm just generally curious about a good way to cleanly sort A so its order matches B where B is a list of values for an attributes of A.

asked Mar 19, 2020 at 1:16
\$\endgroup\$
1
  • \$\begingroup\$ Did you notice that if you have duplicate products you only get one product panel? If you are assuming a 1-to-` relationship then that's probably fine... \$\endgroup\$ Commented Apr 3, 2020 at 1:29

1 Answer 1

1
\$\begingroup\$

Your solution looks good to me, I tried some alternatives but they end up being a little more verbose and not adding value that makes it worth.

Also, I don't think it is worth adding one more step to order it just to use select.

I would go with your first solution.

answered Apr 15, 2020 at 20:08
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.