概要
なんとなく色々な言語向けにPythonのRange関数と同等の処理を行うコードをまとめた。
まず、Pythonのrange関数をおさらい。
range(a,b c)
# a=連番の初期値
# b=連番の上限(ただし、この値は含まれない)
# c=ステップ値
詳細は公式ドキュメント参照。
上記のa,b,cの変数を定義して処理書くこととする。
返ってくる値が特殊型だったりすると困ることもあるので、とりあえず言語ごとに用意された動的配列的な型に代入することとした。
あとは昇順のみとする。
ステップ値を負にすると狂いそうなやつもあるのでそれは随時修正のこと。
実装
Python
# Range List for Python
a=1;b=20;c=3
rng=list(range(a,b,c))
for i in rng:
print(i)
[実装]
今回の基準となるrange関数。
リストに包んだだけ。特筆なし。
C++
// Range List for C++
#include <iostream>
#include <vector>
#include <cmath>
#include <numeric>
using namespace std;
int main(){
int a=1,b=20,c=3;
vector<int> rng(ceil((float)(b-a)/c));
iota(rng.begin(),rng.end(),0);
for(auto &i:rng) i=a+i*c;
for(auto i:rng){
cout<<i<<endl;
}
return 0;
}
[実装]
C++11からのiotaが使える。
素直な関数として書けない辺り凄くC言語らしい。
ステップ値は設定できないので後処理で加える。
初期値は設定できるけど、ステップ値と一緒に処理を加えた方が楽。
D
// Range List for D
import std.stdio;
import std.range;
void main(){
int a=1,b=20,c=3;
auto rng=iota(a,b,c).array();
foreach(i;rng){
writeln(i);
}
}
[実装]
Pythonのrangeとほぼ同じ仕様のiotaがある。
arrayで配列に変換。
C#
// Range List for C#
using System;
using System.Collections.Generic;
using System.Linq;
class Program{
static void Main(){
int a=1,b=20,c=3;
var rng=Enumerable.Range(0,(int)Math.Ceiling((float)(b-a)/c))
.Select(i=>a+i*c)
.ToList();
foreach(var i in rng){
Console.WriteLine(i);
}
}
}
[実装]
rangeと名に付くEnumerable.Rangeが使える。
ステップ値の設定はできないみたい。
なのでLINQの後加工でいい感じに。
JavaScript
// Range List for JavaScript
"use strict";
(function(){
var a=1,b=20,c=3;
var rng=[...Array(0|Math.ceil((b-a)/c))]
.map((_,i)=>0|a+i*c);
for(let i of rng){
console.log(i);
}
})();
[実装]
元々JavaScriptはrange的な構文を持ち合わせていなかったが、スプレッド構文やArray.fromの追加によって比較的容易に連番の配列を生成できるようになった。
連番の追加方法もArray.keysまたはArray.mapの第2引数など何通りかある。
初期値とステップ値はArray.mapで追加する。
VisualBasic.NET
' Range List for VisualBasic.NET
Option Strict On
Option Infer On
Imports System.Collections.Generic
Imports System.Linq
Module Program
Sub Main()
Dim a=1,b=20,c=3
Dim rng=Enumerable.Range(0,CInt(Math.Ceiling((b-a)/c))) _
.Select(Function(i)a+i*c) _
.ToList()
For Each i In rng
Console.WriteLine(i)
Next
End Sub
End Module
[実装]
C#と同じ。
特記なし。
HSP
; Range List for HSP
#runtime "hsp3cl"
#incliude "hspmath"
a=1:b=20:c=3
dim rng,ceil(double(b-a)/c)
foreach rng: rng.cnt=a+cnt*c: loop
foreach rng
mes rng.cnt
loop
HSPには専用の構文は存在しない。
配列を生成して、foreachを回して連番と初期値とステップ値を追加。
CommonLisp
; Range List for CommonLisp
(let ((a 1) (b 20) (c 3))
(let ((rng (loop for i from a below b by c collect i)))
(dolist(i rng)
(format t "~A~%" i))))
[実装]
loopマクロのcollectで柔軟に連番のリストが生成できる。
降順にする場合はbelowをaboveに変更すること。
Scheme
; Range List for Scheme
(import (srfi :1)) ;Sagittarius
;(use srfi-1) ;Gauche
;(use-module (srfi srfi-1) ;Guile
(let ((a 1) (b 20) (c 3))
(let ((rng (iota (ceiling (/ b c)) a c)))
(for-each
(lambda(i)
(display i)(newline))
rng)))
[実装]
SRFI 1にiotaが存在する。
Pythonのrangeとは違い、上限値が生成要素数になっていることを注意。
Clojure
; Range List for Clojure
(let [a 1,b 20,c 3]
(let [rng (range a b c)]
(doseq[i rng]
(println i))))
[実装]
Pythonと同仕様のrangeが存在。
特筆なし。
あとがき
たまーにこういうどうでもいいプログラムを書きたくなる。