SitePoint Sponsor

User Tag List

Results 1 to 8 of 8

Hybrid View

  1. #1
    SitePoint Zealot RyaninZion's Avatar
    Join Date
    Jul 2003
    Location
    Jerusalem
    Posts
    158
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Parsing xml feed

    I need to parse a remote xml file for my site. I found the FeedTools library to be the easiest method, but have now run into a problem.

    The xml file I am parsing has 10 news items. I want to display only 5 of them. How can I limit the output using Ruby iterators?

  2. #2
    SitePoint Zealot RyaninZion's Avatar
    Join Date
    Jul 2003
    Location
    Jerusalem
    Posts
    158
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I guess what I really need to know is if I provide an array with 10 items, can I somehow cause alter this: @feed.items.each do |feed_item| to only show 5 of the items instead of all?

  3. #3
    SitePoint Zealot
    Join Date
    Nov 2004
    Location
    Yakima WA.
    Posts
    100
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
     @feed.items.each_with_index do |feed_item, index|
          puts feed_item if index < 4
    end

  4. #4
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I see your each_with_index and raise you:

    Code:
    @feed.items[0...5].each do |feed_item|
      puts feed_item
    end

  5. #5
    SitePoint Zealot RyaninZion's Avatar
    Join Date
    Jul 2003
    Location
    Jerusalem
    Posts
    158
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Perfect! Thanks so much.


    Quote Originally Posted by Luke Redpath
    I see your each_with_index and raise you:

    Code:
    @feed.items[0...5].each do |feed_item|
      puts feed_item
    end

  6. #6
    SitePoint Zealot
    Join Date
    Nov 2004
    Location
    Yakima WA.
    Posts
    100
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Luke Redpath
    I see your each_with_index and raise you:

    Code:
    @feed.items[0...5].each do |feed_item|
      puts feed_item
    end

    OK since we are raising the stakes I will see you [0...5].each and raise you to:

    Code:
    @feed.items.collect_every(5) {|x| p x}
    And here of course is the raise ;-) This is the implemetation of Array#collect_every:

    Code:
    class Array
      def collect_every(n,fill=false,offset=0)
        
        if block_given?
          while offset < size
            ret=[]
    
            if fill
              n.times do |x| 
                if offset+x > size - 1: ret << nil
                else ret << self[offset+x] end
              end
            else
              n.times { |x| ret << self[offset+x] unless offset+x > size-1 }
            end
    
            offset += n
            yield ret
            ret = nil
          end
        
        else
          ret = []
          while offset < size
            ret << []
            
            if fill
              n.times do |x|
                if offset+x > size - 1: ret.last << nil
                else ret.last << self[offset+x] end
              end
            else
              n.times { |x| ret.last << self[offset+x] unless offset+x > size-1 }
            end
            
            offset += n
          end
          return ret
        end
        
      end
    end
    So that makes the @feed.items.collect_every(5) {|x| p x} work easily but it also gets you a ton of other cool array operations:

    ---------------------------------------------------------------------------
    collect_every(n [,fill=false[,offset=0]]) => an array
    collect_every(n [,fill=false[,offset=0]]) {|item| block} => an_array
    ---------------------------------------------------------------------------
    If a block is given, it invokes the block passing in an array of n elements.
    The last array passed may not contain n elements if size % 2 does not equal
    zero. If no block is given, it returns an array containing the collections.

    If the optional argument fill is set to true, the empty spaces will be
    filled with nils. The optional argument offset allows the collection to
    start at that index in the array.

    a = (1..10).to_a
    a.collect_every(5) #=> [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
    a.collect_every(5) {|x| p x} #=> [1, 2, 3, 4, 5]
    [6, 7, 8, 9, 10]
    b = (1..7).to_a
    b.collect_every(3) #=> [[1, 2, 3], [4, 5, 6], [7]]
    b.collect_every(3,true) #=> [[1, 2, 3], [4, 5, 6], [7,nil,nil]]
    b.collect_every(3,true,1) #=> [[2, 3, 4], [5, 6, 7]]

    So i admit this is way more complicated then a simple iterator ;-) But i had fun implementing this exercise.

    Cheers-
    -Ezra

  7. #7
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Just in case you aren't familiar with Ruby's Range operators, don't forget that .. is inclusive and ... isn't. Because arrays are zero-indexed, I thought it was clearer to use 0...5 instead of 0..4

  8. #8
    SitePoint Zealot RyaninZion's Avatar
    Join Date
    Jul 2003
    Location
    Jerusalem
    Posts
    158
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Excellent. Thanks again.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •