我知道它在许多编程语言中都是一种常见的模式(主要是功能性的),但我不确切地知道它是如何调用的。 所以我有一个数据结构,例如列表A和其他列表B.列表A包含一些值(中文字符串),我想将这些字符串映射到列表B,将它们翻译成英语。所谓的地图和变异。有人可以告诉我这个模式是如何正确命名的,并给出了在Objective-C,Java,Haskell等中实现的一些链接。
答案 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 ++ 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。
我对Obj-C的熟悉程度与我提到的其他人不太一样,但该主题似乎已在this SO post进行了彻底的讨论。
答案 1 :(得分:3)
此模式通常称为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);
}