Linqr - Query Comprehensions for Ruby

Linq ( msdn.microsoft.com/en-us/vcsharp/aa336746 )like sytax for ruby.

Linq in C# is a great example of bringing a uniform query model to different sources of Data. Different providers can be hooked into the model so developers can still use the familiar sytax to query the data source instead of learning a whole new api.

Usage

Querying enumerable

  • Quering an array

    numbers = [ 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 ]
    output =  _{ 
      from x
      in_ numbers
      where (x == 3 ||  x == 5 || x == 8) && ( x % 2) == 0
      select x * 3
    }
    output.should == [24]
    
  • Quering a hash

     hash = {:a => 1 , :b => 2 , :c => 3}
     output = _{
       from k,v
       in_ hash
       where v == 3
       select k
     }
    output.should == [:c]
    
  • Grouping(select can select into anonymous types)

    numbers = [ 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 ]
    number_groups = _{
      from n 
      in_ numbers
      where n > 3 && n < 100
      group_by n % 5  => :g
      select :remainder => g.key , :values => g.values
    }
    number_groups.collect(&:remainder).should == [0, 4, 1, 3, 2]
    
  • Ordering

    words = [ "cherry", "apple", "blueberry" ]
    sorted_words = _{
      from word 
      in_ words
      order_by word.length
      select word
    }
    sorted_words.should == ["apple", "cherry", "blueberry"]
    
  • Selecting into anonymous types

    products = [Product.new("shoes", 1.75), Product.new("glasses", 55.55), Product.new("pencil", 5.20)]
    
    cheap_product_names = _{
      from p
      in_ products 
      where p.price < 10
      select :name => "Cheap - #{p.name}" , :new_price => p.price + 10
    }
    
    cheap_product_names.collect(&:name).should == ["Cheap - shoes","Cheap - pencil"]
    cheap_product_names.collect(&:new_price).should == [11.75, 15.20]
    

Querying ActiveRecord Models

All the examples listed for enumerable should work with activerecord models too

   grouped_by_name = _{
       from o 
       in_ Order
       order_by o.name
       group_by o.name   => :g
       select :name => g.key , :orders => g.values
     }

Querying Groupon Api

output =  _{·
  from deal
  in_  GrouponDeals
  where deal.lat == 38.8339 && deal.lng == -104.821·
  select deal
}