两个参数记忆化

发布于 2024-07-15 01:24:44 字数 211 浏览 15 评论 0原文

在 C# 中,如何记忆具有两个参数的函数?

在记忆之前我必须咖喱吗?

Wes Dyer 编写了记忆化代码 我通常使用,但现在我需要两个参数

In C# how do I memoize a function with two arguments?

Do I have to curry before memoization?

Wes Dyer wrote the Memoization code I typically use, but now I need two arguments

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

不可一世的女人 2024-07-22 01:24:44

您只需制作 Memoize 方法的重载版本,该方法具有三种泛型类型,并采用带有两个参数的函数和两个实参。 它仍然返回一个无参数函数:

public static Func<R> Memoize<A1,A2,R>(this Func<A1,A2,R> f, A1 a1, A2 a2)
{
  R value = default(R);
  bool hasValue = false;
  return () =>
    {
      if (!hasValue)
      {
        hasValue = true;
        value = f(a1,a2);
      }
      return value;
    };
}

编辑:
或者,您需要为包含两个参数的 KeyValuePair 创建一个自定义 IEqualityComparer,以便 Memoize 方法能够返回具有两个参数的函数:

public static Func<A1,A2,R> Memoize<A1,A2,R>(this Func<A1,A2,R> f, IEqualityComparer<KeyValuePair<A1,A2>> comparer)
{
   var map = new Dictionary<KeyValuePair<A1,A2>,R>(comparer);
   return (a1,a2) =>
      {
         R value;
         KeyValuePair<A1,A2> key = new KeyValuePair<A1,A2>(a1,a2);
         if (map.TryGetValue(key, out value)) {
            return value;
         }
         value = f(a1,a2);
         map.Add(key, value);
         return value;
      };
}

You just make an overloaded version of the Memoize method that has three generic types and takes a function with two parameters, and the two arguments. It still returns a parameterless function:

public static Func<R> Memoize<A1,A2,R>(this Func<A1,A2,R> f, A1 a1, A2 a2)
{
  R value = default(R);
  bool hasValue = false;
  return () =>
    {
      if (!hasValue)
      {
        hasValue = true;
        value = f(a1,a2);
      }
      return value;
    };
}

Edit:
Alternatively, you need to make a custom IEqualityComparer for a KeyValuePair that contains the two arguments, for the Memoize method to be able to return a function with two parameters:

public static Func<A1,A2,R> Memoize<A1,A2,R>(this Func<A1,A2,R> f, IEqualityComparer<KeyValuePair<A1,A2>> comparer)
{
   var map = new Dictionary<KeyValuePair<A1,A2>,R>(comparer);
   return (a1,a2) =>
      {
         R value;
         KeyValuePair<A1,A2> key = new KeyValuePair<A1,A2>(a1,a2);
         if (map.TryGetValue(key, out value)) {
            return value;
         }
         value = f(a1,a2);
         map.Add(key, value);
         return value;
      };
}
聽兲甴掵 2024-07-22 01:24:44

Wes 还有另一篇文章,他给出了 Memoize 的两个(或更多)参数版本。 它不需要自定义比较器。

Wes has another post where he gives a two (or more) argument version of Memoize. It does not require a custom comparer.

暗藏城府 2024-07-22 01:24:44

使用新版本的 .NET,您可以使用元组稍微简化已接受的解决方案的代码

    public static Func<TParam1, TParam2, TReturn> Memoize<TParam1, TParam2, TReturn>(Func<TParam1, TParam2, TReturn> func)
    {
        var map = new Dictionary<Tuple<TParam1, TParam2>, TReturn>();
        return (param1, param2) =>
        {
            var key = Tuple.Create(param1, param2);
            TReturn result;
            if (!map.TryGetValue(key, out result))
            {
                result = func(param1, param2);
                map.Add(key, result);
            }
            return result;
        };
    }

With new versions of .NET you can simplify the accepted solution's code a bit by using tuples

    public static Func<TParam1, TParam2, TReturn> Memoize<TParam1, TParam2, TReturn>(Func<TParam1, TParam2, TReturn> func)
    {
        var map = new Dictionary<Tuple<TParam1, TParam2>, TReturn>();
        return (param1, param2) =>
        {
            var key = Tuple.Create(param1, param2);
            TReturn result;
            if (!map.TryGetValue(key, out result))
            {
                result = func(param1, param2);
                map.Add(key, result);
            }
            return result;
        };
    }
乜一 2024-07-22 01:24:44

你应该能够记住一对。 这两个 arg 函数调用您记住的单个 arg 函数。

You should be able to memoize a pair. The two arg function calls a single arg function that you memoize.

虫児飞 2024-07-22 01:24:44

我还用 C# 做了一些记忆方面的工作。 我的结果类似,但使用从输入对象哈希码的串联派生的字典键。 该模式可以扩展到与 Func<> 一样多的输入。 会允许。

更多信息请参见:http://bit.ly/t6iNJP

I also did some work on memoization in C#. My results are similar but use a dictionary key derived from the concatenation of the input object hash codes. The pattern can be extended to as many intputs as Func<> will allow.

Se more here: http://bit.ly/t6iNJP

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文