Array.map() あれこれ
関数の中でmapが好きなので、いろいろな言語のmapを調べてみました。
※ここで言うmapは、主に配列(言語によってはリスト)を受け取って、内部で処理して(多くは無名関数などのコールバック関数)、新しい配列を作って返すような言語に込み込みの標準関数を想定しています。
mapの気に入っているところ
個人的に下記が気に入っている理由です。
- ループ処理を書かなくて良い
- 元の配列に影響しない
- コードが短くて済む
JavaScript
ここ1年くらいはJSしか書いてないですが。JSでは、個人的にforやforEachよりもmapを良く使います。
const array = ['Perl', 'Ruby', 'Scala'];
console.log(array);
let array2 = array.map(v => `Hello ${v}!`);
console.log(array2);
Ruby
RubyのmapはArrayクラスの実装では無く、Arrayクラスが継承するEnumerableモジュールにあるんですね。
array = ['Perl', 'Ruby', 'Scala']
p array
array2 = array.map {|v| "Hello #{v}!"}
p array2
Perl
map歴はPerlからですが、Rubyを使った時にPerlとmapへの配列の渡し方が違うので戸惑いました。
my @array = ('Perl', 'Ruby', 'Scala');
print("@array\n");
my @array2 = map { "Hello $_!" } @array;
print("@array2");
Scala
ScalaはJavaとRubyなどのスクリプト言語の手軽さを合わせたような言語です(個人的なイメージ)
val array = List("Perl", "Ruby", "Scala")
println(array)
val array2 = array.map(v => s"Hello $v!")
println(array2)
Clojure
Scalaと同じく、JVM上で動作するLisp記法の言語で関数型と並列処理が強み(個人的なイメージです)
(def array ["Perl" "Ruby" "Scala"])
(println array)
(def array2 (map #(format "Hello %s!" %) array))
(println array2)
https://clojuredocs.org/clojure.core/format
PHP
PHPも無名関数が使えるんですね。
<?php
$array = ['Perl', 'Ruby', 'Scala'];
var_dump($array);
$array2 = array_map(function ($v){return "Hello " . $v . "!";}, $array);
var_dump($array2);
?>
Swift
Swift使ったこと無いですが、型推論があるようでスクリプト言語っぽく書けるので中々良いかもです。
変数の文字列展開は(変数名)な感じで書けます。
let array = ["Perl", "Ruby", "Scala"]
print(array)
let array2 = array.map {"Hello \($0)!"}
print(array2)
Python
大人気言語パイソンです。Pythonでは無名関数の定義にlambdaと言う宣言?を使うようです。
array = ["Perl", "Ruby", "Scala"];
print(array);
array2 = list(map(lambda v: "Hello " + v + "!", array));
print(array2);
lambda
f-string
array2 = list(map(lambda v: f"Hello {v}!", array));
リスト内包表記
Haskell
Haskellです。関数型言語で型推論を持つ言語です。(多分)
main = do
let array = ["Perl", "Ruby", "Scala"]
print array
let array2 = map (\ v -> "Hello " ++ v ++ "!") array
print array2
感想
kintoneアプリ開発の会社に所属している為、普段は限定された範囲のJavaScriptしか書かないのですが、書籍を持っている範囲の言語で1つの関数の使い方をまとめてみると、言語によっていろいろな考え方などを発見することが出来たので、良かったと思います。
JavaScriptで関数言語のような使い方に傾倒しているので、ScalaとClojureは書きやすいなと感じています。(あと、Swiftも意外と違和感が無かった)
参考
動作確認には paiza.IO を利用させていただきました。ありがとうございます。
Go
GoにはArray.map()に相当するものが、そもそも無いようでした。
package main
import "fmt"
func main(){
array := []string{"Perl", "Ruby", "Scala"}
fmt.Println(array)
var array2 []string
for _, v := range array {
array2 = append(array2, "Hello " + v + "!")
}
fmt.Println(array2)
}
Rust
fn main(){
let array = vec!["Perl", "Ruby", "Scala"];
println!("{:?}", array);
let array2: Vec<String> = array.iter().map(|v| format!("Hello, {}!", v)).collect();
println!("{:?}", array2);
}
Java
import java.util.*;
import java.text.*;
public class Main {
public static void main(String[] args) throws Exception {
List<String> array = Arrays.asList("Perl", "Ruby", "Scala");
System.out.println(array);
List<String> array2 = new ArrayList<>();
for (String v : array) {
array2.add(MessageFormat.format("Hello {0}!", v));
}
System.out.println(array2);
}
}
Kotlin
fun main(args: Array<String>) {
val array = mutableListOf("Perl", "Ruby", "Scala")
println(array)
val array2 = mutableListOf<String>()
for (v in array) {
array2.add("Hello ${v}!")
}
println(array2)
}