将数据从一个数据结构映射到另一个

时间:2013-10-02 14:28:50

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

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

2 个答案:

答案 0 :(得分:7)

此过程称为“映射”或“映射和变异”(如您所述),可以映射的数据类型可以是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上搜索您喜欢的数据结构并查看来源。

命令式语言

虽然在命令式语言中,3元素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提供了类似的构造,但没有自动类型推断或需要显式引用:

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

扩展Iterable也是explained elsewhere

目标C

我对Obj-C的熟悉程度与我提到的其他人不太一样,但该主题似乎已在this SO post进行了彻底的讨论。

答案 1 :(得分:3)

此模式通常称为mapapply,具体取决于语言。我将使用的例子是将数字列表[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);
}