2011-11-09 30 views
3

我想在Ruby中編寫一個類似於此C#代碼的代碼。Ruby中的LINQ功能

它接收候選拓撲集合和世界集合,並測試候選拓撲是否是關於世界的拓撲。

在C#中使用LINQ功能,它看起來像這樣:

public static bool IsTopology<T>(IEnumerable<IEnumerable<T>> candidate, IEnumerable<T> world) 
{ 
    IEqualityComparer<IEnumerable<T>> setComparer = 
     new SetComparer<T>(); 

    if (!candidate.Contains(Enumerable.Empty<T>(), setComparer) || 
     !candidate.Contains(world, setComparer)) 
    { 
     return false; 
    } 

    var pairs = 
     from x in candidate 
     from y in candidate 
     select new {x,y}; 

    return pairs.All(pair => candidate.Contains(pair.x.Union(pair.y), setComparer) && 
     candidate.Contains(pair.x.Intersect(pair.y), setComparer)); 
} 

public class SetComparer<T> : IEqualityComparer<IEnumerable<T>>   
{ 
    public bool Equals (IEnumerable<T> x, IEnumerable<T> y) 
    { 
     return new HashSet<T>(x).SetEquals(y); 
    } 

    public int GetHashCode (IEnumerable<T> obj) 
    { 
     return 0; 
    } 
} 

我要找的特點如下:

  • 堵塞的相等比較器方法的能力

  • 使用嵌套地圖(和匿名類型)的能力

  • 比較數組作爲套的能力(不是很重要的它缺少了一點,在C#中...)

我相信紅寶石具有的功能,我非常有興趣看的等同的代碼是什麼樣子喜歡。

+1

你'的GetHashCode()'是極其緩慢。您應該使用'HashSet'和http://msdn.microsoft.com/en-us/library/bb335475.aspx。 – SLaks

+0

如果您更熟悉.NET的LINQ並需要緊急完成此操作,則可以使用IronRuby,它允許您混合使用Ruby和.NET代碼。但是,如果你有時間,學習如何做到這一點,那麼Ruby方式就是要走的路 –

回答

3

我翻譯你的代碼,以紅寶石(和重寫它一下):

# candidate - Enumerable of Enumerable; world - Enumerable; &block - comparer of two sets. 
    def topology? candidate, world, &block 
    require 'set' 
    # you can pass block to this method or if no block passed it will use set comparison 
    comparer = block || lambda { |ary1,ary2| ary1.to_set.eql?(ary2.to_set) } 
    # create lambda-function to find a specified set in candidate (to reuse code) 
    candidate_include = lambda { |to_find| candidate.find {|item| comparer.(item, to_find) } } 

    return false if(!candidate_include.([]) || !candidate_include.(world)) 

    pairs = candidate.to_a.repeated_permutation(2) 

    pairs.all? do |x,y| x_set = x.to_set; y_set = y.to_set 
     candidate_include.(x_set & y_set) && # or x_set.intersection y_set 
     candidate_include.(x_set | y_set) # or x_set.union y_set 
    end 
    end 

希望這有助於