简体   繁体   中英

get previous and next elements within and ordered collection

Within a collection of components, one member is the active member.

@components = Component.order(id: :asc, sequence_order: :asc)
@component_ids = @components.pluck('id')
@present_component = Component.where('id = ?', params[:component_id]).first

To take advantage of turbolinks, the goal is to identify the previous and next items within this ordered collection. How can the previous component be extracted?

 index = @components.find_index(@present_component.id)
 @previous = @components[index-1]

fails; I'd like to understand why.

The @components object is a list of Components, not Component ids, so you have to search like this:

 index = @components.find_index(@present_component)

or maybe you wanted to do this:

 index = @components_ids.find_index(@present_component.id)
def neighbors(arr, item)
  idx = arr.index(item)
  return nil if idx.nil?
  return [nil, arr[idx+1]] if idx.zero?
  arr.values_at(idx-1, idx+1)
end

neighbors(["cat", "dog", "pig"], "dog")  #=> ["cat", "pig"] 
neighbors(["cat", "dog", "pig"], "owl")  #=> nil
neighbors(["cat", "dog", "pig"], "cat")  #=> [nil, "dog"] 
neighbors(["cat", "dog", "pig"], "pig")  #=> ["dog", nil] 
neighbors(["cat"], "cat")                #=> [nil, nil] 
neighbors([], "cat")                     #=> nil 

Notice that:

  • if idx = nil , nil is returned;
  • else if arr.size = 1 , [,nil, nil] is returned;
  • else if idx = 0 , [,nil, arr[1]] is returned;
  • else if idx = arr.size-1 , [,arr[-1], nil] is returned;
  • else [,arr[idx-1], arr[Iidx+1] is returned.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM