Pythonに似たJavaScriptの関数はありrange()ますか?
毎回次の行を書くよりも良い方法があるはずだと思います。
array = new Array();
for (i = 0; i < specified_len; i++) {
array[i] = i;
}
回答:
いいえ、ありませんが、作成できます。
range()Pythonでどのように機能するかをエミュレートしようとすると、次のような関数を作成します。
function range(start, stop, step) {
if (typeof stop == 'undefined') {
// one param defined
stop = start;
start = 0;
}
if (typeof step == 'undefined') {
step = 1;
}
if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) {
return [];
}
var result = [];
for (var i = start; step > 0 ? i < stop : i > stop; i += step) {
result.push(i);
}
return result;
};
証拠については、このjsfiddleを参照してください。
range()JavaScriptとPythonの比較これは次のように機能します。
range(4)を返します[0, 1, 2, 3]、range(3,6)を返します[3, 4, 5]、range(0,10,2)を返します[0, 2, 4, 6, 8]、range(10,0,-1)を返します[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]、range(8,2,-2)を返します[8, 6, 4]、range(8,2)を返します[]、range(8,2,2)を返します[]、range(1,5,-1)を返します[]、range(1,5,-2)を返します[]、そしてそれに対応するPythonはまったく同じように機能します(少なくとも前述の場合):
>>> range(4)
[0, 1, 2, 3]
>>> range(3,6)
[3, 4, 5]
>>> range(0,10,2)
[0, 2, 4, 6, 8]
>>> range(10,0,-1)
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
>>> range(8,2,-2)
[8, 6, 4]
>>> range(8,2)
[]
>>> range(8,2,2)
[]
>>> range(1,5,-1)
[]
>>> range(1,5,-2)
[]
したがって、Pythonと同様に機能する関数が必要なrange()場合は、上記のソリューションを使用できます。
stopがより大きいことを確認しますstart(そうでない場合はそれらを交換します)。
start >= stopこの関数range()がPythonのように動作するには単純では不十分であるため、チェックはより複雑になる可能性があります。回答を更新しました。
ES6の非常に単純な範囲の場合:
let range = n => Array.from(Array(n).keys())
bigOmegaのコメントから、これはSpread構文を使用して短縮できます。
let range = n => [...Array(n).keys()]
let range = n => [...Array(n).keys()]
constは可能な限り使用しようとしますが、ここでは配列への参照にすぎないため、配列は引き続き編集可能です: 'D
constは、戻り値ではなく、関数自体に適用されます。おそらく、関数を変更したくないでしょう。
2018:この回答は賛成票を集め続けているので、ここに更新があります。以下のコードは廃止されましたが、幸いなことにES6で標準化されたジェネレーターとyieldキーワードであり、プラットフォーム間で広くサポートされています。怠け者の例range()使用をyield見つけることができるここに。
すでにJavascriptの1.7以降がサポートを提供、言っているものに加えてイテレータとジェネレータの怠惰、メモリ効率の高いバージョンを作成するために使用することができrangeにsimlar、xrange:Python2での
function range(low, high) {
return {
__iterator__: function() {
return {
next: function() {
if (low > high)
throw StopIteration;
return low++;
}
}
}
}
}
for (var i in range(3, 5))
console.log(i); // 3,4,5
step引数も実装して、私の答えの値でテストできますか?あなたの答えは、私たちが非常に特定のブラウザを念頭に置いているアプリケーションに最適です(9より前のバージョンのGoogle Chrome、Safari、IEでは機能しません:stackoverflow.com/a/2209743/548696)。
range「最後の」値は除外されています(したがって、上記のコードの>=代わりに使用する必要が>あります)
@Tadeckと@georgからの両方の回答を融合して、私はこれを思いついた:
function* range(start, stop, step = 1) {
if (stop == null) {
// one param defined
stop = start;
start = 0;
}
for (let i = start; step > 0 ? i < stop : i > stop; i += step) {
yield i;
}
}
forループで使用するには、ES6 /JS1.7のfor-ofループが必要です。
for (let i of range(5)) {
console.log(i);
}
// Outputs => 0 1 2 3 4
for (let i of range(0, 10, 2)) {
console.log(i);
}
// Outputs => 0 2 4 6 8
for (let i of range(10, 0, -2)) {
console.log(i);
}
// Outputs => 10 8 6 4 2
stepパラメータが、ときstopに渡されていない、両方startとstop変更する必要があります。更新します
rangePython 2の関数の移植版は、underscore.jsおよびlodashユーティリティライブラリ(および他の多くの便利なツール)によって提供されます。アンダースコアドキュメントからコピーされた例:
_.range(10);
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
_.range(1, 11);
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
_.range(0, 30, 5);
=> [0, 5, 10, 15, 20, 25]
_.range(0, -10, -1);
=> [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
_.range(0);
=> []
Numberプロトタイプにイテレータを取り付けることで実現できます
Number.prototype[Symbol.iterator] = function* () {
for (var i = 0; i <= this; i++) {
yield i
}
}
[...5] // will result in [0,1,2,3,4,5]
カイルシンプソンのコース「非同期JavaScriptの再考」からの抜粋
範囲の開始位置と終了位置の両方を指定する必要がある場合に備えて、回答の1つを少し拡張したものを次に示します。
let range = (start, end) => Array.from(Array(end + 1).keys()).slice(start);
どうぞ。
これにより、各インデックスの値がインデックス番号で書き込まれます(または上書きされます)。
Array.prototype.writeIndices = function( n ) {
for( var i = 0; i < (n || this.length); ++i ) this[i] = i;
return this;
};
数値を指定しない場合は、配列の現在の長さが使用されます。
次のように使用します。
var array = [].writeIndices(10); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
ES6のデフォルトパラメータでさらに洗練されています。
let range = function*(start = 0, stop, step = 1) {
let cur = (stop === undefined) ? 0 : start;
let max = (stop === undefined) ? start : stop;
for (let i = cur; step < 0 ? i > max : i < max; i += step)
yield i
}
以下は、Pythonのrange()関数をJavaScriptに自然に適応させたものです。
// Generate range from start (inclusive) to stop (exclusive):
function* range(start, stop, step = 1) {
if (stop === undefined) [start, stop] = [0, start];
if (step > 0) while (start < stop) yield start, start += step;
else if (step < 0) while (start > stop) yield start, start += step;
else throw new RangeError('range() step argument invalid');
}
// Examples:
console.log([...range(3)]); // [0, 1, 2]
console.log([...range(0, 3)]); // [0, 1, 2]
console.log([...range(0, 3, -1)]);// []
console.log([...range(0, 0)]); // []
console.log([...range(-3)]); // []
console.log([...range(-3, 0)]); // [-3, -2, -1]
これは、と比較することができ、任意の引数をサポート0し、stopかつずつ増加することができますがstep。を超えない数で使用すると、Pythonバージョンと同じように動作しますNumber.MAX_SAFE_INTEGER。
次のコーナーケースに注意してください。
[...range(0, 0, 0)]; // RangeError: range() step argument invalid
[...range(Number.MAX_SAFE_INTEGER + 1, Number.MAX_SAFE_INTEGER + 2)]; // []
[...range(Number.MAX_SAFE_INTEGER + 2, Number.MAX_SAFE_INTEGER + 3)]; // Infinite loop
[...range(0.7, 0.8, 0.1)]; // [0.7, 0.7999999999999999]
[...range('1', '11')]; // ['1']
[...range('2', '22')]; // Infinite loop
対照的に、@ Tadeckさん、VOLVの@と@ janka102の答えはこれリターン[]、undefinedまたは時に無限ループに入るstep評価さに0かNaN、この生成関数はPythonの行動のような例外がスローされます。
pythonicrangeJSのジェネレーター(yield)を使用してPythonの動作を最もよく模倣し、range(stop)とrange(start, stop, step)ユースケースの両方をサポートします。また、pythonicのrange関数が返すIteratorサポートしているのPythonに似たオブジェクトをmapしてfilter:1のような空想のワンライナーを行うことができますので、
import {range} from 'pythonic';
// ...
const results = range(5).map(wouldBeInvokedFiveTimes);
// `results` is now an array containing elements from
// 5 calls to wouldBeInvokedFiveTimes
を使用してインストールnpm:
npm install --save pythonic
開示私はPythonicの作成者およびメンテナーです
MDNはこのアプローチを推奨しています:シーケンスジェネレーター(範囲)
// Sequence generator function (commonly referred to as "range", e.g. Clojure, PHP etc)
const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
// Generate numbers range 0..4
console.log("range(0, 4, 1):", range(0, 4, 1));
// [0, 1, 2, 3, 4]
// Generate numbers range 1..10 with step of 2
console.log("\nrange(1, 10, 2):", range(1, 10, 2));
// [1, 3, 5, 7, 9]
// Generate the alphabet using Array.from making use of it being ordered as a sequence
console.log("\nrange('A'.charCodeAt(0), 'Z'.charCodeAt(0), 1).map(x => String.fromCharCode(x))", range('A'.charCodeAt(0), 'Z'.charCodeAt(0), 1).map(x => String.fromCharCode(x)));
// ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
Pythonのrange()に似たJavaScriptの関数はありますか?
ここでのすべてのソリューションは、Python 2の範囲を参照しています(おそらく、提供したコード例が原因です)。ただし、Python 3では、range()メソッドはイテレータを返します。JavaScriptにもイテレータがあり、配列全体を生成してメモリに格納するよりもスペース効率が高くなります。
したがって、Python3のrange(n)関数のより正確な表現はですArray(n).keys()。
例えば:
for (let i of Array(n).keys()) {
console.log(i) // 0, 1, 2, 3, ..., n
}
もう1つの例(他の回答ですでに説明されています)。イテレータを配列に変換する(ES6):
let ary = [...Array(n).keys()];
// ary = [0, 1, 2, 3, ..., n]
と同等の組み込み関数はまだありませんrange()が、最新バージョンであるES2015を使用すると、独自の実装を構築できます。これが限定版です。ステップパラメータが考慮されていないため、制限されています。最小、最大
const range = (min = null, max = null) =>
Array.from({length:max ? max - min : min}, (v,k) => max ? k + min : k)
これはArray.from、lengthプロパティを持つ任意のオブジェクトから配列を構築できるメソッドによって実現されます。したがって、lengthプロパティのみを含む単純なオブジェクトを渡すと、オブジェクトのlength数を生成するArrayIteratorが作成されます。
これが私の好みの方法です。Pythonのように1つまたは2つの入力を指定できます。
function range(start, end) {
return Array.from(Array(end||start).keys()).slice(!!end*start)
}
これes6が範囲の別の実装です
// range :: (from, to, step?) -> [Number]
const range = (from, to, step = 1) => {
//swap values if necesery
[from, to] = from > to ? [to, from] : [from, to]
//create range array
return [...Array(Math.round((to - from) / step))]
.map((_, index) => {
const negative = from < 0 ? Math.abs(from) : 0
return index < negative ?
from + index * step :
(index - negative + 1) * step
})
}
range(-20, 0, 5)
.forEach(val => console.log(val))
for(const val of range(5, 1)){
console.log(`value ${val}`)
}
-20への配列を生成したい場合はどうなり-30ますか?
いいえ、ありませんが、作成できます。
私は範囲のPython3の振る舞いに部分的です。以下に、JavaScriptによるPythonのrange()の実装を示します。
function* range(start=0, end=undefined, step=1) {
if(arguments.length === 1) {end = start, start = 0}
[...arguments].forEach(arg => {
if( typeof arg !== 'number') {throw new TypeError("Invalid argument")}
})
if(arguments.length === 0) {throw new TypeError("More arguments neede")}
if(start >= end) return
yield start
yield* range(start + step, end, step)
}
// Use Cases
console.log([...range(5)])
console.log([...range(2, 5)])
console.log([...range(2, 5, 2)])
console.log([...range(2,3)])
// You can, of course, iterate through the range instance.
Pythonのrange()に似たJavaScriptの関数はありますか?
前に答えたように:いいえ、ありません。しかし、あなたはあなた自身のものを作ることができます。これはES6にとって興味深いアプローチだと思います。Python 2.7range()と非常によく似ていますが、はるかに動的です。
function range(start, stop, step = 1)
{
// This will make the function behave as range(stop)
if(arguments.length === 1)
{
return [...Array(arguments[0]).keys()]
}
// Adjusts step to go towards the stop value
if((start > stop && !(step < 0)) ||
(start < stop && !(step > 0)))
{
step *= -1
}
let returnArray = []
// Checks if i is in the interval between start and stop no matter if stop
// is lower than start or vice-versa
for(let i = start; (i-start)*(i-stop) <= 0; i += step)
{
returnArray.push(i)
}
return returnArray
}
この関数は、3つの異なる方法で動作できます(Pythonのrange()のように)。
range(stop)range(start, stop)range(start, stop, step)これらの例:
console.log(range(5))
console.log(range(-2, 2))
console.log(range(2, -2))
console.log(range(10, 20, 2))
次の出力が得られます。
[ 0, 1, 2, 3, 4 ]
[ -2, -1, 0, 1, 2 ]
[ 2, 1, 0, -1, -2 ]
[ 10, 12, 14, 16, 18, 20 ]
in演算子(Pythonなど)を使用して配列を反復処理する代わりに、を使用する必要があることに注意してくださいof。したがって、i変数は配列の要素のインデックスではなく値を想定します。
for(let i of range(5))
{
// do something with i...
}
NodeJのオプションは、バッファーを使用することです。
[...Buffer.alloc(5).keys()]
// [ 0, 1, 2, 3, 4 ]
良い点は、バッファーで直接反復できることです。
Buffer.alloc(5).forEach((_, index) => console.log(index))
// 0
// 1
// 2
// 3
// 4
初期化されていない配列ではそれを行うことはできません。
Array(5).forEach((_, index) => console.log(index))
// undefined
しかし、彼らの正しい心の中で誰がこのような目的のためにバッファを使用します;)
これが私がそれをする方法です
let n = 5
[...Array(n).keys()].map(x=>{console.log(x)})
出力
0
1
2
3
4
range()動作をエミュレートすることを目的とした関数を作成したので、それを使用できます。JavaScriptにはそのような関数はありませんがRange、MooToolsのクラスなど、さまざまなフレームワーク用のプラグインがいくつかあります。