【问题标题】:Mapping data from one data structure to another将数据从一种数据结构映射到另一种
【发布时间】:2013-10-08 23:38:31
【问题描述】:

我知道它是许多编程语言(主要是函数式)中相当常见的模式,但我不知道它是如何调用的。 所以我有一个数据结构,例如列表 A 和其他列表 B。列表 A 包含一些值(中文字符串),我想将这些字符串映射到列表 B,将它们翻译成英文。所谓的地图和变异。有人可以告诉这个模式是如何正确命名的,并给出它在 Objective-C 、 Java 、 Haskell 等中的实现的链接。

【问题讨论】:

  • 我回答了,但后来意识到我认为您问的问题与我回答的问题不同。您能否澄清一下 - 例如,一些示例输入以及您期望的输出?
  • @ChrisTaylor 谢谢!不,不。你的回答完全让我满意。这就是我所寻求的。我只是认为它以某种不同的方式被调用。您可以再次发布您的答案,以便我接受。
  • 啊,好吧。我已经取消删除它。

标签: java design-patterns haskell map functional-programming


【解决方案1】:

这个过程被称为“映射”或“映射和变异”(正如你提到的),可以映射的数据类型可以是 Haskell 中 Functor 类型类的实例(注意使用了“函子”在 C++ 中有所不同)。此外,在命令式语言中,此过程可以使用 foreach 样式的循环来完成。

功能语言

许多函数式语言为列表提供map 的默认实现,也可能为其他数据类型提供默认实现。例如,列表映射的 Haskell 实现是:

map :: (a -> b) -> [a] -> [b]
map _ []     = []
map f (x:xs) = f x : map f xs

chineseToEnglish :: [String] -> [String]
chineseToEnglish chineseStrings = map translate chineseStrings

对于更复杂的数据结构,存在更复杂的示例。尝试在 Hoogle 上搜索您最喜欢的数据结构并查看源代码。

命令式语言

虽然在命令式语言中,三元素 for 循环提供了迭代数组的标准方法,但 C++11、Java 和 Obj-C 也都有更多与映射相关的 for 循环。

C++

C++11 在其新的 ranged-for 循环中提供了对迭代器的抽象:

vector<string> chinese;
for (auto &s : chinese) {
    translate(s);
}

将iterator 类扩展为explained elsewhere

Java

Java 提供了类似的构造,但没有自动类型推断或显式引用的需要:

ArrayList<LanguageString> chinese = new ArrayList();
for (LanguageString s : chinese) {
    s.translate();
}

扩展 Iterable 也已扩展为 explained elsewhere。

目标-C

我不像我提到的其他人那样熟悉 Obj-C,但该主题似乎已在 this SO post 进行了深入讨论。

【讨论】:

    【解决方案2】:

    此模式通常称为map 或apply,具体取决于语言。我将使用的示例是将数字列表 [1, 2, 3, 4, 5] 转换为它们的正方形 [1, 4, 9, 16, 15]。

    在函数式编程语言中,这通常很简单。例如,在 Haskell 中

    >> let numbers = [1, 2, 3, 4, 5]
    >> map (\x -> x^2) numbers
    [1, 4, 9, 16, 25]
    

    在 R 中,这是一门具有功能感觉的语言

    >> numbers = c(1, 2, 3, 4, 5)
    >> sapply(numbers, function(x) {x^2})
    [1] 1  4  9 16 25
    

    或者在 Python 中

    >> numbers = [1, 2, 3, 4, 5]
    >> map(lambda x: x**2, numbers)
    [1, 4, 9, 16, 25]
    

    在不支持一流函数的语言(如 Java)中,您通常为此使用循环:

    int[] numbers = {1, 2, 3, 4, 5};
    int[] result  = new int[5];
    
    for (i = 0; i < numbers.length; i++)
    {
        result[i] = Math.pow(numbers[i], 2);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-23
      • 2021-04-11
      • 2011-05-30
      • 2019-08-27
      • 1970-01-01
      • 2013-01-29
      相关资源
      最近更新 更多