いろんな言語比較してみた

# 軽く比較🍻
書いた見た目を比較するだけ。
実装内容は
- **文字列**の`配列(系のやつ)`の初期化、追加、末尾削除
- のディープコピー
- をフィルタするだけ
- をフィルタしつつ出力

を関数にして呼び出すものとします。まぁ準備運動ですね。👯‍♂️

言語は以下です。
筆者が扱える言語が少ないのでこれだけですが、おいおい増やしたいと思います。

- JavaScript
- Python
- Go
- Java
- Rust
- C++
- SQL
- zsh
- vimscript

# JavaScript
これがいちばんすき😎😎
```js
/**
 * test
 */
(() => {
    // 配列
    list = ["test", "test"]
    list.push("add")
    list.pop(0)
    // 配列を移す
    _ = [...list] // これは非破壊だがシャローコピー
    _ = JSON.parse(JSON.stringify(list)) // これはディープコピー
    _ = structuredClone(list) // こちらの方が良い（循環参照もいける）
    // フィルタのみ
    _ = list.filter(v => v === "test")
    // フィルタして出力
    list.filter(v => v === "test").forEach(console.log)
})()
```

# Python
短いねぇ！🤭
```py
import copy

def test():
    """test
    """
    # 配列
    list = ["test", "test"]
    list.append("add")
    list.pop(-1)
    # 配列を移す
    _ = [v for v in list] # これはシャローコピー
    _ = list.copy() # これもシャローコピー
    _ = list[:] # これもシャローコピー
    import copy
    _ = copy.deepcopy(list) # こちらがディープコピー
    # フィルタのみ
    _ = [v for v in list if v == "test"]
    # フィルタして出力
    for v in list:
        if v == "test":
            print(v)

test()
```

# Go
好きだけど使いこなせてないです…🤔
> ディープコピー等、sliceについて[こちら](https://zenn.dev/mattn/articles/31dfed3c89956d)のmattnさんの記事と
> @htsign さんよりいただきました[こちら](https://qiita.com/neras_1215/items/dc26a6539e7d7f1b5991#comment-01b770dd00eaf96270f5)のコメントより修正しました。
```go
package main

import "fmt"

/*
test
*/
func test() {
    // 配列
    list := [] string{"test","test"}
    list = append(list, "add")
    list = append(list[:len(list)-1])
    // 配列を移す
    cop := make([]string, len(list))
    copy(cop, list)
    cop_ := append(list[:0:0], list...) // これはシャローっぽい
    fmt.Println(cop) // unusedでエラーになるので出力
    fmt.Println(cop_) // unusedでエラーになるので出力
    // フィルタのみ
    var fil []string
    for _, v := range list {
        if v == "test" {
            fil = append(fil, v)
        }
    }
    // フィルタして出力
    for _, v := range list {
        if v == "test" {
            fmt.Println(v)
        }
    }
}
func main() {
    test()
}
```

# Java
仕事で一番多く使っています。飽きた😣
```java
package main;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        /** test */
        Runnable test = () -> {
            // 配列
            List<String> list = new LinkedList<>(Arrays.asList("test", "test"));
            list.add("add");
            list.remove(list.size() - 1);
            // 配列を移す
            @SuppressWarnings("unused")
            List<String> copy = new LinkedList<>(list); // これはObject型の場合はディープにならない
            List<String> cop2 = new LinkedList<>();
            for (String v : list) {
                cop2.add(new String(v)); // 要素のオブジェクトを一つずつnewして別インスタンスにすればディープ
            }
            // フィルタのみ
            @SuppressWarnings("unused")
            List<String> fil = list.stream().filter("test"::equals).collect(Collectors.toList());
            // フィルタして出力
            list.stream().filter("test"::equals).forEach(System.out::println);
        };
        test.run();
    }
}
```

# Rust
まだあまり使ったことがないのでもっと色々知りたい😏
```rust
/*
test
*/
fn test() {
    // 配列
    let mut list = vec!["test", "test"];
    list.push("add");
    list.pop();
    // 配列を移す
    let _ = list.to_vec(); // Cloneトレイトを実装した型はcloneメソッドによってオブジェクトのコピーしたほうがよさげ、今回は怠ける
    // フィルタのみ
    let _: Vec<String> = list.iter().filter(|&v| *v == "test").map(|&v| v.to_string()).collect();
    // フィルタして出力
    let _: Vec<String> = list.iter().filter(|&v| *v == "test").inspect(|&v| println!("{}", *v)).map(|&v| v.to_string()).collect();
}
fn main() {
    test();
}
```

# C++
なんだかんだCが最強💪
```cpp
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)

int main() {
    /** test */
    auto test = []() -> void{
        // 配列
        vector<string> list = {"test", "test"};
        list.push_back("add");
        list.pop_back();
        // 配列を移す
        vector<string> copy(list);
        // フィルタのみ
        vector<string> fil;
        rep(i, list.size()) if (list[i] == "test") fil.push_back(list[i]);
        // フィルタして出力
        rep(i, list.size()) if (list[i] == "test") cout << list[i] << endl;
    };
    test();
    return 0;
}
```

# SQL
プロシージャはPL/pgSQLで書きました🐘
ちなみにSQLiteが軽くて好きです🪶
```sql
DROP TABLE IF EXISTS list;
DROP TABLE IF EXISTS cop;
CREATE TABLE list (test varchar(64));
CREATE TABLE cop (test varchar(64));

-- test
DROP FUNCTION IF EXISTS TEST();
CREATE OR REPLACE FUNCTION TEST() RETURNS VOID AS $$
    DECLARE
        GET_ARR VARCHAR := 'SELECT ''test'', ''test''';
        GET_RES VARCHAR;

        INSERT_QUERY VARCHAR := 'INSERT INTO list (test) VALUES (''test''), (''test''), (''add'')';
        DELETE_QUERY VARCHAR := 'DELETE FROM list WHERE test = ''test''';

        MOVE_QUERY VARCHAR := 'INSERT INTO cop (test) SELECT test FROM list';

        FILTER_QUERY VARCHAR := 'SELECT * FROM list WHERE test = ''test''';
        FIL_RES VARCHAR;

        FIL CURSOR IS SELECT * FROM list WHERE test = 'test';
        COLUMN_VAR VARCHAR;

    BEGIN
        -- 配列？
        EXECUTE GET_ARR INTO GET_RES;

        EXECUTE INSERT_QUERY;
        EXECUTE DELETE_QUERY;

        -- 配列？を移す
        EXECUTE MOVE_QUERY;

        -- フィルタのみ
        EXECUTE FILTER_QUERY INTO FIL_RES;

        -- フィルタして出力
        COLUMN_VAR := '';
        OPEN FIL;
        LOOP
            FETCH FIL INTO COLUMN_VAR;
            EXIT WHEN NOT FOUND;
            IF COLUMN_VAR = 'test' THEN
                RAISE NOTICE '%', COLUMN_VAR;
            END IF;
        END LOOP;
        CLOSE FIL;
    END;
$$ LANGUAGE 'plphsql';

SELECT TEST();
```

# zsh
zshといいつつshellですね…🍎
```sh
# test
Test() {
    # 配列
    list=("test" "test")
    list+=("add")
    unset list[-1]
    # 配列を移す
    cop=()
    for v in ${list[@]}; do
        cop+=($v)
    done
    # フィルタのみ
    fil=()
    for v in ${list[@]}; do
        if [ $v == "test" ]; then
            fil+=($v)
        fi
    done
    # フィルタして出力
    for v in ${list[@]}; do
        if [ $v == "test" ]; then
            echo $v
        fi
    done
}
Test
```

# vimscript
プラグイン作りまくってるのでめっちゃ書いてます。vimは神✨
```vim
" test
fu! Test() abort
    " 配列
    let list = ["test", "test"]
    cal add(list, "add")
    cal remove(list, len(list) - 1)
    " 配列を移す
    let cop = deepcopy(list)
    " フィルタのみ(破壊的)
    cal filter(list, { _, v -> v == "test" })
    " フィルタして出力
    for v in list
        if v == "test"
            echo v
        endif
    endfor
    " または、例えばlsコマンド結果文字列に対して
    for v in system('git ls-files -c')->split('\n')->filter({_,v->!empty(v)})->map({_,v->v.split('/')[-1]})
        echo v
    endfor
endf
cal Test()
```