我需要一种更好的方法来查询数组
I need a better way to query an array
我有一个与可缩放媒体链接的 T 恤应用 api。我有一个可行的解决方案,但必须有更好的方法。 api 有一系列颜色的产品,颜色有一组图像。我想显示 "Front" 的图像,但数组中的第一张图像并不总是在前面。我的视野狭窄,因为我想不出比这更好的解决方案来查询数组中的标签 "Front"....
查看:
<% if @product['colors'][0]['images'][0]['label'] =='Front' %>
<%= image_tag @product['colors'][0]['images'][0]['url'] %>
<% elsif @product['colors'][0]['images'][1]['label'] =='Front' %>
<%= image_tag @product['colors'][0]['images'][1]['url'] %>
<% elsif @product['colors'][0]['images'][2]['label'] =='Front' %>
<%= image_tag @product['colors'][0]['images'][2]['url'] %>
<% elsif @product['colors'][0]['images'][3]['label'] =='Front' %>
<%= image_tag @product['colors'][0]['images'][3]['url'] %>
<% end %>
控制器:
def show_product
@product = scalable_press.show_product(params[:product])
end
有更好的方法吗?
使用find
:
<% item = @product['colors'][0]['images'].find{|i| i['label'] == 'Front'} %>
<%= image_tag item['url'] if item.present? %>
您可以创建一个方便的地图:
image_map = @product['colors'][0]['images'].each_with_object({}) do |h,obj|
obj[h["label"]] = h["url"]
ebd
现在,您可以访问各种图片 URL:
image_map["Right"]
#=> "http://i1.ooshirts.com/images/lab_shirts/Kiwi-5-R.jpg"
image_map["Left"]
#=> "http://i1.ooshirts.com/images/lab_shirts/Kiwi-5-L.jpg"
我正在使用 here 中的示例 JSON,您最好向其中添加一个 link。
每次我必须处理我无法控制的数据结构时,我都会创建一个 class 来将该数据结构包装成我自己喜欢的样子。我在上面看到的最大问题是你 link 的 API 结构与你的观点,想象一下一旦 API 改变就重构它。
module <ExternalAPIName>
IMAGE_TYPES = {
front: "Front"
...
}
class Product
attr_reader :colors
def self.get(product)
# Depending on what scalable_press is you can either call it directly or declare module attribute
new scalable_press.show_product(product)
end
def initialize(data_hash)
parse_colors(data_hash['colors'])
end
private
def parse_colors(colors)
@colors = colors.map {|color_hash| Color.new(color_hash) }
end
end
class Color
def initialize(color_hash)
parse_images color_hash['images']
end
IMAGE_TYPES.each do |name, label|
define_method "#{name}_image" do
@images.find {|image| image.type == name }
end
end
private
def parse_images(images)
@images = images.map {|image_hash| Image.new(image_hash) }
end
end
class Image
attr_reader :url, :type
def initialize(data_hash)
@url = data_hash['url']
@type = IMAGE_TYPES.key(data_hash['label'])
end
end
end
相当多的代码,我同意,但它在很大程度上简化了您的其余代码:
控制器:
@product = ExternalAPIName.get(params[:product])
查看:
<%= image_tag(@product.colors.first.front_image.url) %>
它为您提供了对收到的数据的完全自定义能力,最重要的是,您将嵌套的哈希结构转换为属于您的应用程序域的对象。您现在可以将任何过滤、搜索和数据操作方法挂接到这些对象中。
我有一个与可缩放媒体链接的 T 恤应用 api。我有一个可行的解决方案,但必须有更好的方法。 api 有一系列颜色的产品,颜色有一组图像。我想显示 "Front" 的图像,但数组中的第一张图像并不总是在前面。我的视野狭窄,因为我想不出比这更好的解决方案来查询数组中的标签 "Front"....
查看:
<% if @product['colors'][0]['images'][0]['label'] =='Front' %>
<%= image_tag @product['colors'][0]['images'][0]['url'] %>
<% elsif @product['colors'][0]['images'][1]['label'] =='Front' %>
<%= image_tag @product['colors'][0]['images'][1]['url'] %>
<% elsif @product['colors'][0]['images'][2]['label'] =='Front' %>
<%= image_tag @product['colors'][0]['images'][2]['url'] %>
<% elsif @product['colors'][0]['images'][3]['label'] =='Front' %>
<%= image_tag @product['colors'][0]['images'][3]['url'] %>
<% end %>
控制器:
def show_product
@product = scalable_press.show_product(params[:product])
end
有更好的方法吗?
使用find
:
<% item = @product['colors'][0]['images'].find{|i| i['label'] == 'Front'} %>
<%= image_tag item['url'] if item.present? %>
您可以创建一个方便的地图:
image_map = @product['colors'][0]['images'].each_with_object({}) do |h,obj|
obj[h["label"]] = h["url"]
ebd
现在,您可以访问各种图片 URL:
image_map["Right"]
#=> "http://i1.ooshirts.com/images/lab_shirts/Kiwi-5-R.jpg"
image_map["Left"]
#=> "http://i1.ooshirts.com/images/lab_shirts/Kiwi-5-L.jpg"
我正在使用 here 中的示例 JSON,您最好向其中添加一个 link。
每次我必须处理我无法控制的数据结构时,我都会创建一个 class 来将该数据结构包装成我自己喜欢的样子。我在上面看到的最大问题是你 link 的 API 结构与你的观点,想象一下一旦 API 改变就重构它。
module <ExternalAPIName>
IMAGE_TYPES = {
front: "Front"
...
}
class Product
attr_reader :colors
def self.get(product)
# Depending on what scalable_press is you can either call it directly or declare module attribute
new scalable_press.show_product(product)
end
def initialize(data_hash)
parse_colors(data_hash['colors'])
end
private
def parse_colors(colors)
@colors = colors.map {|color_hash| Color.new(color_hash) }
end
end
class Color
def initialize(color_hash)
parse_images color_hash['images']
end
IMAGE_TYPES.each do |name, label|
define_method "#{name}_image" do
@images.find {|image| image.type == name }
end
end
private
def parse_images(images)
@images = images.map {|image_hash| Image.new(image_hash) }
end
end
class Image
attr_reader :url, :type
def initialize(data_hash)
@url = data_hash['url']
@type = IMAGE_TYPES.key(data_hash['label'])
end
end
end
相当多的代码,我同意,但它在很大程度上简化了您的其余代码:
控制器:
@product = ExternalAPIName.get(params[:product])
查看:
<%= image_tag(@product.colors.first.front_image.url) %>
它为您提供了对收到的数据的完全自定义能力,最重要的是,您将嵌套的哈希结构转换为属于您的应用程序域的对象。您现在可以将任何过滤、搜索和数据操作方法挂接到这些对象中。