Javascriptでこのようなものを簡単に書く方法はありますか?
[1,2,3].times do {
something();
}
同様の構文をサポートする可能性のあるライブラリはありますか?
更新:something()
明確にするために-配列要素の反復ごとにそれぞれ1、2、3回呼び出されたい
Javascriptでこのようなものを簡単に書く方法はありますか?
[1,2,3].times do {
something();
}
同様の構文をサポートする可能性のあるライブラリはありますか?
更新:something()
明確にするために-配列要素の反復ごとにそれぞれ1、2、3回呼び出されたい
for
ループを使用するだけです。
var times = 10;
for(var i = 0; i < times; i++){
doSomething();
}
可能なES6の代替。
Array.from(Array(3)).forEach((x, i) => {
something();
});
そして、あなたがそれを「それぞれ1、2、3回呼ばれる」ようにしたいのなら。
Array.from(Array(3)).forEach((x, i) => {
Array.from(Array(i+1)).forEach((x, i2) => {
console.log(`Something ${ i } ${ i2 }`)
});
});
これは、初期配列を作成するためのより最適化された方法のようです。また、@felix-eveによって提案された2番目のパラメーターマップ関数を使用するようにこれを更新しました。
Array.from({ length: 3 }, (x, i) => {
something();
});
Array.forEach
この回答は、ライブラリなしで、ネイティブバニラのみに基づいています。
基本的にsomething()
3回呼び出すには、次を使用します。
[1,2,3].forEach(function(i) {
something();
});
次の機能を考慮します。
function something(){ console.log('something') }
出力は次のようになります。
something
something
something
この質問を完了するには、次の方法でsomething()
それぞれ1、2、3回電話をかけます。
[1,2,3].forEach(i => Array(i).fill(i).forEach(_ => {
something()
}))
[1,2,3].forEach(function(i) {
Array(i).fill(i).forEach(function() {
something()
})
}))
どちらの場合も、出力は次のようになります
出力は次のようになります。
something
something
something
something
something
something
(1回、次に2回、次に3回)
fill
すべてのアイテムを作成します。undefined
map
map
定義されていない配列項目をスキップする理由の詳細を読む
⚠️Array.fill
はIEをサポートしていません
Array(5).fill().map((item, i) => console.log(item, i))
または、アイテムの値が設定されていない場合は、アイテムごとに自動的に設定される配列を破棄して、フィルなしで上記と同じように実行します。 undefined
[...Array(5)].map((item, i) => console.log(item, i))
上記をより「宣言的」にしたい場合、私の現在の意見ベースの解決策は次のようになります。
const iterate = times => callback => [...Array(times)].map((n,i) => callback(i))
iterate(3)(console.log)
// run 5 times:
for( let i=5; i--; )
console.log(i)
または宣言型の「while」として:
const run = (cb, ...args) => count => { while(count--) cb(...args) }
// executes the callback with whatever arguments, 3 times
run(console.log, 1,2,3)(3)
アンダースコアについて言及しているので:
f
呼び出したい関数であると仮定します。
_.each([1,2,3], function (n) { _.times(n, f) });
トリックを行います。たとえば、を使用f = function (x) { console.log(x); }
すると、コンソールにアクセスできます。
0 0 1 0 1 2
次のように、破壊して同じことを行うこともできます
[...Array(3)].forEach( _ => console.log('do something'));
またはインデックスが必要な場合
[...Array(3)].forEach(( _, index) => console.log('do something'));
Underscorejsを使用できない場合は、自分で実装できます。NumberプロトタイプとStringプロトタイプに新しいメソッドをアタッチすることで、次のように実行できます(ES6矢印関数を使用)。
// With String
"5".times( (i) => console.log("number "+i) );
// With number variable
var five = 5;
five.times( (i) => console.log("number "+i) );
// With number literal (parentheses required)
(5).times( (i) => console.log("number "+i) );
(任意の名前の)関数式を作成し、それにアクセスしたい任意のプロパティ名(プロトタイプ上)に次のように割り当てるだけです。
var timesFunction = function(callback) {
if (typeof callback !== "function" ) {
throw new TypeError("Callback is not a function");
} else if( isNaN(parseInt(Number(this.valueOf()))) ) {
throw new TypeError("Object is not a valid number");
}
for (var i = 0; i < Number(this.valueOf()); i++) {
callback(i);
}
};
String.prototype.times = timesFunction;
Number.prototype.times = timesFunction;
アンダースコアやロダッシュに似ていますが、より強力なラムダと呼ばれる素晴らしいライブラリがあります。
const R = require('ramda');
R.call(R.times(() => {
console.log('do something')
}), 5);
Ramdaには便利な機能がたくさん含まれています。Ramdaのドキュメントを参照してください
あなたが使用することができます
Array.forEach
例:
function logArrayElements(element, index, array) {
console.log("a[" + index + "] = " + element);
}
[2, 5, 9].forEach(logArrayElements)
またはjQueryを使用
$.each([52, 97], function(index, value) {
alert(index + ': ' + value);
});
var times = [1,2,3];
for(var i = 0; i < times.length; i++) {
for(var j = 0; j < times[i];j++) {
// do something
}
}
jQueryの使用.each()
$([1,2,3]).each(function(i, val) {
for(var j = 0; j < val;j++) {
// do something
}
});
また
var x = [1,2,3];
$(x).each(function(i, val) {
for(var j = 0; j < val;j++) {
// do something
}
});
あなたは純粋なJSで以下のようにすることができます:
var times = [1,2,3];
times.forEach(function(i) {
// do something
});
ネストされたループを使用するだけです(関数で囲まれている可能性があります)
function times( fct, times ) {
for( var i=0; i<times.length; ++i ) {
for( var j=0; j<times[i]; ++j ) {
fct();
}
}
}
次に、次のように呼び出します。
times( doSomething, [1,2,3] );
times = function () {
var length = arguments.length;
for (var i = 0; i < length ; i++) {
for (var j = 0; j < arguments[i]; j++) {
dosomthing();
}
}
}
あなたはそれをこのように呼ぶことができます:
times(3,4);
times(1,2,3,4);
times(1,3,5,7,9);
// calls doSomething 42 times
Array( 42 ).join( "x" ).split( "" ).forEach( doSomething );
と
// creates 42 somethings
var somethings = Array( 42 ).join( "x" ).split( "" ).map( () => buildSomething(); );
または( https://stackoverflow.com/a/20066663/275501経由)
Array.apply(null, {length: 42}).forEach( doSomething );
const loop (fn, times) => {
if (!times) { return }
fn()
loop(fn, times - 1)
}
loop(something, 3)
function doSomthing() {
...
}
そのようにそれを使用してください:
Array.from(Array(length).keys()).forEach(doSomthing);
または
Array.from({ length }, (v, i) => i).forEach(doSomthing);
または
// array start counting from 1
Array.from({ length }, (v, i) => ++i).forEach(doSomthing);
これらの答えはすべて良好で、IMO @Andreasが最適ですが、JSでは多くの場合、非同期で処理を行う必要があります。その場合、非同期で対応できます。
http://caolan.github.io/async/docs.html#times
const async = require('async');
async.times(5, function(n, next) {
createUser(n, function(err, user) {
next(err, user);
});
}, function(err, users) {
// we should now have 5 users
});
これらの「回」機能は、ほとんどのアプリケーションコードには非常に役立ちますが、テストには役立つはずです。
与えられた関数something
:
function something() { console.log("did something") }
そして、プロトタイプtimes
に追加された新しいメソッド:Array
Array.prototype.times = function(f){
for(v of this)
for(var _ of Array(v))
f();
}
このコード:
[1,2,3].times(something)
これを出力します:
did something
did something
did something
did something
did something
did something
更新された質問(5年後)に答えると思いますが、これをアレイで機能させることはどれほど役立つのでしょうか?効果は、を呼び出すことと同じではないでしょうか。これは、次の[6].times(something)
ように書くことができます。
for(_ of Array(6)) something();
(ただし、_
ジャンク変数として使用すると、使用している場合は、おそらくlodashまたはアンダースコアが表示されます)
およびを使用Array.from
し.forEach
ます。
let length = 5;
Array.from({length}).forEach((v, i) => {
console.log(`#${i}`);
});
Spread演算子のようなES6構文を使用できると仮定すると、コレクション内のすべての数値の合計と同じ回数だけ何かを実行する必要があります。
この場合、時間がに等しい場合[1,2,3]
、合計回数は6回、つまり1 + 2+3になります。
/**
* @param {number[]} times
* @param {cb} function
*/
function doTimes(times, cb) {
// Get the sum of all the times
const totalTimes = times.reduce((acc, time) => acc + time);
// Call the callback as many times as the sum
[...Array(totalTimes)].map(cb);
}
doTimes([1,2,3], () => console.log('something'));
// => Prints 'something' 6 times
この投稿は、配列の構築と拡散の背後にあるロジックが明らかでない場合に役立ちます。
TypeScriptの実装:
String.times
実装方法とNumber.times
タイプセーフで動作する方法に興味のある方はthisArg
、ここに行きます:
declare global {
interface Number {
times: (callbackFn: (iteration: number) => void, thisArg?: any) => void;
}
interface String {
times: (callbackFn: (iteration: number) => void, thisArg?: any) => void;
}
}
Number.prototype.times = function (callbackFn, thisArg) {
const num = this.valueOf()
if (typeof callbackFn !== "function" ) {
throw new TypeError("callbackFn is not a function")
}
if (num < 0) {
throw new RangeError('Must not be negative')
}
if (!isFinite(num)) {
throw new RangeError('Must be Finite')
}
if (isNaN(num)) {
throw new RangeError('Must not be NaN')
}
[...Array(num)].forEach((_, i) => callbackFn.bind(thisArg, i + 1)())
// Other elegant solutions
// new Array<null>(num).fill(null).forEach(() => {})
// Array.from({length: num}).forEach(() => {})
}
String.prototype.times = function (callbackFn, thisArg) {
let num = parseInt(this.valueOf())
if (typeof callbackFn !== "function" ) {
throw new TypeError("callbackFn is not a function")
}
if (num < 0) {
throw new RangeError('Must not be negative')
}
if (!isFinite(num)) {
throw new RangeError('Must be Finite')
}
// num is NaN if `this` is an empty string
if (isNaN(num)) {
num = 0
}
[...Array(num)].forEach((_, i) => callbackFn.bind(thisArg, i + 1)())
// Other elegant solutions
// new Array<null>(num).fill(null).forEach(() => {})
// Array.from({length: num}).forEach(() => {})
}
いくつかの例を含むTypeScriptPlaygroundへのリンクはここにあります
この投稿は、AndreasBergström 、Vinyl 、Ozay Duman、およびSeregPieによって投稿されたソリューションを実装しています。
追加しようと思ったのですが.repeat(n)
、文字列'n'を何度も繰り返す気の利いたJSメソッドがあります。したがって、文字列'n'を何度も繰り返すものを探している場合は...
function repeatString (number, string) {
return string.repeat(number);
}
だからあなたがしたなら...
repeatString(3, 'Hey there! ');
あなたが得るだろう:'ねえ、そこに!ちょっと、そこ!ちょっと、そこ!'