5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

いろんな言語で数値のrangeを作って文字列でjoinした

Posted at

次の処理を色んな言語1で書いてみた。2言語ごとに特徴が出てて面白かったです。

「range的な関数で作った1から始まる数列を、join的な関数で,区切りでくっつける。」

スクリプト言語

perl

# perl 5, version 18, subversion 2 (v5.18.2)

# 終端を含む
print(join(",", (1..10)), "\n")
# => 1,2,3,4,5,6,7,8,9,10

php

# PHP 7.0.6

# 終端を含む
echo join(",", range(1, 10)), "\n";
# => 1,2,3,4,5,6,7,8,9,10
  • join関数はimplode関数のエイリアスなので、implode(",", range(1, 10));でもOK。

ruby

# ruby 2.2.3

# 終端を含まない
puts (1...10).map(&:to_s).join(",")
# => 1,2,3,4,5,6,7,8,9

# 終端を含む
puts (1..10).map(&:to_s).join(",")
# => 1,2,3,4,5,6,7,8,9,10
  • .....がどっちがどっちかいつも不安になる。

python

# Python 3.5.1

# 終端を含まない
print(",".join(map(str, range(1, 10))))
# => 1,2,3,4,5,6,7,8,9
  • 2系の場合、そのままだと上記のprint関数はエラーになる。 from __future__ import print_functionしておけば動く。
  • 3系のrange関数の実装は、2系だとxrange関数のほうが近いらしい。これらは遅延評価されるが、2系range関数はその範囲の値を全て最初にメモリに展開するようです。

javascript

// node v6.2.1

s1 = [...Array(10).keys()].map(n => n+1).join(',');
console.log(s1);
//=> 1,2,3,4,5,6,7,8,9,10

s2 = Array.from(Array(10).keys()).map(n => n+1).join(',')
console.log(s2);
//=> 1,2,3,4,5,6,7,8,9,10

// 終端を含まない by Underscore.js
s3 = _.range(1, 10).join(',');
console.log(s3);
//=> 1,2,3,4,5,6,7,8,9

// 終端を含まない by immutable-js
s4 = Immutable.Range(1, 10).toArray().join(',');
console.log(s4);
//=> 1,2,3,4,5,6,7,8,9
  • 素のJSで1から始まるrangeを直接取得する方法が分からなかった。。

JVM言語

java

package jp.sample;

import java.util.stream.IntStream;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) throws Exception {
        // 終端を含まない
        String s1 = String.join(",", IntStream.range(1, 10).boxed().map(n -> n.toString()).collect(Collectors.toList()));
        System.out.println(s1);
        //=> 1,2,3,4,5,6,7,8,9

        // 終端を含む
        String s2 = String.join(",", IntStream.rangeClosed(1, 10).boxed().map(n -> n.toString()).collect(Collectors.toList()));
        System.out.println(s2);
        //=> 1,2,3,4,5,6,7,8,9,10
    }
}

scala

// Scala 2.10.6

// 終端を含まない (1)
println(Range(1, 10).mkString(","))
//=> 1,2,3,4,5,6,7,8,9

// 終端を含まない (2)
println((1 until 10).mkString(","))
//=> 1,2,3,4,5,6,7,8,9

// 終端を含む
println((1 to 10).mkString(","))
//=> 1,2,3,4,5,6,7,8,9,10

clojure

; Clojure 1.8.0

(require '[clojure.string :refer [join]])

; 終端を含まない (1)
(println (join \, (range 1 10)))
;=> 1,2,3,4,5,6,7,8,9

; 終端を含まない (2) スレッディングマクロ
(->> 10 (range 1) (join \,) println)
;=> 1,2,3,4,5,6,7,8,9

CLR言語

c-sharp

// mono-3.2.8.0 (C#5, CLI4.5)

public class Hello{
    public static void Main(){
        // 終端を含む
        System.Console.WriteLine(string.Join(",", System.Linq.Enumerable.Range(1, 10)));
        //=> 1,2,3,4,5,6,7,8,9,10
    }
}

f-sharp

// F# 3.0 (Open Source Edition) / mono-3.2.8.0

// 終端を含む
System.Console.WriteLine([1..10] |> List.map (fun n -> n.ToString()) |> String.concat ",")
//=> 1,2,3,4,5,6,7,8,9,10

システムプログラミング言語

rust

// rustc 1.8.0

fn main() {
    // 終端を含まない
    let s: String = (1..10).map(|n| n.to_string()).collect::<Vec<String>>().join(",");
    println!("{}", s)
    //=> 1,2,3,4,5,6,7,8,9
}

go

// go 1.4.2

package main
import (
    "fmt"
    "strings"
    "strconv"
)

func main(){
    var a []string = make([]string, 10)
    for i := 0; i < 10; i++ {
        a[i] = strconv.Itoa(i+1)
    }
    fmt.Println(strings.Join(a, ","))
    //=> 1,2,3,4,5,6,7,8,9,10
}
  • rangeを直接作る方法は見つけられなかった。。

その他

swift

// Swift version 2.2

// 終端を含まない
print((1..<10).map { n in String(n) }.joinWithSeparator(","))
//=> 1,2,3,4,5,6,7,8,9

// 終端を含む
print((1...10).map { n in String(n) }.joinWithSeparator(","))
//=> 1,2,3,4,5,6,7,8,9,10

haskell

-- GHCi, version 7.10.3

-- 終端を含まない (1) 
putStrLn (intercalate "," (map (\n -> show n) [1..10]))
-- => 1,2,3,4,5,6,7,8,9

-- 終端を含まない (2) リスト内包
putStrLn (intercalate "," [show n | n <- [1..10]])
-- => 1,2,3,4,5,6,7,8,9

shell

# zsh version 5.0.8

# 終端を含む
a=`seq -s"," 1 10` && echo ${a%,}
# => 1,2,3,4,5,6,7,8,9,10
  • 変数aを使っているので、なんとなく他とやり方が違う感じがあるが、自分にはここまでしか分からなかった。
  • shellはまだまだやり方がたくさんありそう。

まとめ

メソッドをチェーンして書ける言語はどれもだいたい同じ感じになった。

rangeオブジェクトみたいなのを直接作れる言語の場合、要素の型がだいたい数値になると思うけど、それを文字列に変換(map)する一手間がある言語とない言語と。強い型付け/弱い型付けの違い以外にjoin的関数が内部でtoString()的処理をするように実装してるかどうかの違いも関わってくる。

..とか...で作られるrangeオブジェクトに終端の数値が含まれるかどうかが、言語によってまちまち。覚えるのの諦めがついた。

ScalaのmkStringは各言語のjoin的関数の上位互換だと思う。とても便利。

参考

  1. 自分が触ったことがある言語だけなので、そんなに多くはないです。

  2. もとはJava8でrangeが作れるのか調べていて脱線した。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?