【问题标题】:LINQ features in RubyRuby 中的 LINQ 功能
【发布时间】:2011-12-25 14:29:52
【问题描述】:

我想用 Ruby 编写一个行为类似于 C# 代码的代码。

它接收一个候选拓扑集和一个世界集,并测试候选拓扑是否是一个相对于世界的拓扑。

在使用 LINQ 功能的 C# 中,它看起来像这样:

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# 中它缺少一点...)

我相信 ruby​​ 具有这些功能,并且很想看看等效代码的样子。

【问题讨论】:

  • 您的GetHashCode() 非常慢。您应该改用HashSets 和msdn.microsoft.com/en-us/library/bb335475.aspx
  • 如果您对 .NET 的 LINQ 比较熟悉并且需要紧急完成这项工作,您可以使用 IronRuby,它允许您混合 Ruby 和 .NET 代码。不过,如果你有时间,学习用 Ruby 的方式来做这件事就是要走的路

标签: c# ruby linq topology


【解决方案1】:

我将您的代码翻译成 ruby​​(并稍作改写):

  # 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

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 2011-06-27
    • 1970-01-01
    • 1970-01-01
    • 2011-02-28
    • 1970-01-01
    相关资源
    最近更新 更多