rails if对象位于数组中

时间:2021-04-10 21:15:39

I need to check, if for each item in @line_items if it is in different array say @quote_items

我需要检查@line_items中的每个条目,如果它在不同的数组中,比如@quote_items

Controller:

控制器:

def index
  @line_items = LineItem.all
  @quote_items = QuoteItem.all
end

View:

观点:

<% for line_item in @line_items %>
   <% if @quote_items.include?(line_item) %>
     line_item in quote item! 
   <% else %>
     line_item NOT in quote item! 
   <% end %>
...
<% end %>

Is there an easy way to do this? include? doesn't seem to work the way I want. Seems to just yield false for me all the the time.

有简单的方法吗?包括什么?似乎不像我想的那样。对我来说似乎一直都是假的。

3 个解决方案

#1


5  

You are right it will always return false because you are trying to check if the array of @quote_items has a line item object

您是正确的,它总是返回false,因为您试图检查@quote_items数组是否有一个行项对象。

@quote_items.include?(line_item)

which obviously will always be false because your @quote_items instance is an array of QuoteItem objects and @line_items instance is an array of LineItem object. So they are always different objects.

因为@quote_items实例是QuoteItem对象的数组,@line_items实例是LineItem对象的数组。所以它们总是不同的物体。

I think in this situation you may want to compare some common attribute of quote_item and line_item. For example if you want to compare name attribute then

我认为在这种情况下,您可能需要比较quote_item和line_item的一些常见属性。例如,如果您想比较name属性

quote_item_names = @quote_items.map(&:name)

and then

然后

<% if quote_item_names.include?(line_item.name) %>
 line_item in quote item! 
<% else %>
 line_item NOT in quote item! 
<% end %>

#2


3  

Like it was pointed out in discussion above — it depends on which criterion you're comparing objects in 2 arrays.

正如上面的讨论所指出的那样——这取决于您在两个数组中比较对象的标准。

  • If objects are of the same class (or the same ancestor), then include? will work.
  • 如果对象属于相同的类(或相同的祖先),则包含?将工作。
  • If objects are different, and you only want to compare their ids (although this makes little sense), it'd be something like this:

    如果对象是不同的,并且您只想比较它们的id(尽管这没有什么意义),它应该是这样的:

    line_item_ids = @line_items.map(&:id) # array of just the attribute we need
    @quote_items.each do |quote_item|
      if line_item_ids.include?(quote_item.id)
        # line item with the same id found
      else
        # ...
      end
    end
    

    You can do the above with any attribute, not just id.

    您可以使用任何属性来完成上面的操作,而不仅仅是id。

  • If in both cases your objects are plain strings or symbols, make sure you're converting everything to string or symbol. Sometimes I forget and comparisons end up being false.

    如果在这两种情况下,对象都是普通的字符串或符号,请确保将所有内容转换为字符串或符号。有时我忘记了,而比较最终是错误的。

#3


1  

@line_items & @quote_items should return an array that includes the common items between them. @line_items - @quote_items return items that are in @line_items but not in @quote_items.Your code should work though, are you sure there are common items between them? Note that item equality is checked by the == operator, so you might need to provide that for your item class.

@line_items & @quote_items应该返回一个包含它们之间公共项的数组。@line_items - @quote_items返回@line_items中但不在@quote_items中的项。但是您的代码应该可以工作,您确定它们之间有公共项吗?注意,==运算符检查了项的相等性,因此您可能需要为您的item类提供这个值。

#1


5  

You are right it will always return false because you are trying to check if the array of @quote_items has a line item object

您是正确的,它总是返回false,因为您试图检查@quote_items数组是否有一个行项对象。

@quote_items.include?(line_item)

which obviously will always be false because your @quote_items instance is an array of QuoteItem objects and @line_items instance is an array of LineItem object. So they are always different objects.

因为@quote_items实例是QuoteItem对象的数组,@line_items实例是LineItem对象的数组。所以它们总是不同的物体。

I think in this situation you may want to compare some common attribute of quote_item and line_item. For example if you want to compare name attribute then

我认为在这种情况下,您可能需要比较quote_item和line_item的一些常见属性。例如,如果您想比较name属性

quote_item_names = @quote_items.map(&:name)

and then

然后

<% if quote_item_names.include?(line_item.name) %>
 line_item in quote item! 
<% else %>
 line_item NOT in quote item! 
<% end %>

#2


3  

Like it was pointed out in discussion above — it depends on which criterion you're comparing objects in 2 arrays.

正如上面的讨论所指出的那样——这取决于您在两个数组中比较对象的标准。

  • If objects are of the same class (or the same ancestor), then include? will work.
  • 如果对象属于相同的类(或相同的祖先),则包含?将工作。
  • If objects are different, and you only want to compare their ids (although this makes little sense), it'd be something like this:

    如果对象是不同的,并且您只想比较它们的id(尽管这没有什么意义),它应该是这样的:

    line_item_ids = @line_items.map(&:id) # array of just the attribute we need
    @quote_items.each do |quote_item|
      if line_item_ids.include?(quote_item.id)
        # line item with the same id found
      else
        # ...
      end
    end
    

    You can do the above with any attribute, not just id.

    您可以使用任何属性来完成上面的操作,而不仅仅是id。

  • If in both cases your objects are plain strings or symbols, make sure you're converting everything to string or symbol. Sometimes I forget and comparisons end up being false.

    如果在这两种情况下,对象都是普通的字符串或符号,请确保将所有内容转换为字符串或符号。有时我忘记了,而比较最终是错误的。

#3


1  

@line_items & @quote_items should return an array that includes the common items between them. @line_items - @quote_items return items that are in @line_items but not in @quote_items.Your code should work though, are you sure there are common items between them? Note that item equality is checked by the == operator, so you might need to provide that for your item class.

@line_items & @quote_items应该返回一个包含它们之间公共项的数组。@line_items - @quote_items返回@line_items中但不在@quote_items中的项。但是您的代码应该可以工作,您确定它们之间有公共项吗?注意,==运算符检查了项的相等性,因此您可能需要为您的item类提供这个值。