Insights on Ruby, Git, jQuery, Cappuccino, WordPress, Debian and OS X. Please subscribe if you find something useful!

Expand Your Twitter Network In Less Than 15 Lines of Ruby

Posted: May 17th, 2009 | Author: Jerod | Filed under: Ruby | Tags: , | Comments

A great way to meet new people on Twitter is by checking out the people your friends are interacting with. We can assume that if many of your friends follow somebody, that person has a high likelihood of being interesting to you (or it is Ashton Kutcher). Let’s use Ruby to generate a list of people highly followed by our friends.

The Flow

  1. fetch the ids of all the people you follow
  2. use those ids to fetch the ids of all the people they follow
  3. remove any ids in both groups (sound familiar?)
  4. tally the occurrences of each unique id in the list
  5. sort them by most occurrences
  6. iterate the top 10 and print the user information

The Script

Some Explanation

The only “tricky” thing I’m doing is making good use of Ruby’s Enumerable#inject method. Twice. This method iterates an enumerable object similar to how ‘each’ does except it takes an argument and passes it through the block with the object it is iterating. The variable passed can be modified and is returned by the method. For a good write-up on ‘inject’, see this blog post by The Budding Rubyist.

A Limitation

Unfortunately, this script is hindered by Twitter’s 100 API calls per hour. If you follow more than 100 people on Twitter you’re going to need a workaround. I’ll leave these as an exercise for whoever is interested, but a few ideas are:

  1. sleep the script between API hits
  2. toggle between multiple accounts for requests
  3. request whitelisting from Twitter

A Challenge

Can you can make this script smaller, more readable, or more robust? I put it on GitHub so you can fork my gist and put a link to your version in the comments!


  • Isn't:

    my_friends.inject(Array.new) { |array,id| array += Twitter.friend_ids(id); array }

    the same as

    my_friends.map { |id| Twitter.friend_ids(id) }.flatten

    (The latter should be *much* faster).

    Otherwise, very cool little script.
  • Yes, I suppose it is. It's also a little easier to read. But why would it be *much* faster than using inject? Is it because adding arrays is slow but flattening an array of arrays is not?
  • It's because of object allocation. inject doesn't accumulate into a single collection, but instead produces a new one every iteration. This is also true of Array#+ but less of a concern. Object creation (and GC) are very slow in Ruby.
blog comments powered by Disqus