次のチェックボックスがあるとします:
<input type="checkbox" value="1-25" />
探している範囲の境界を定義する2つの数値を取得するには、次のjQueryを使用します。
var value = $(this).val();
var lowEnd = Number(value.split('-')[0]);
var highEnd = Number(value.split('-')[1]);
lowEnd
とhighEnd
自体を含むlowEnd
とhighEnd
の間のすべての整数を含む配列を作成するにはどうすればよいですか?この特定の例では、明らかに、結果の配列は次のようになります。
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
var list = [];
for (var i = lowEnd; i <= highEnd; i++) {
list.Push(i);
}
JavaScript ES6の場合:
function range(start, end) {
return Array(end - start + 1).fill().map((_, idx) => start + idx)
}
var result = range(9, 18); // [9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
console.log(result);
完全を期すために、ここではオプションのstep
パラメーターを使用しています。
function range(start, end, step = 1) {
const len = Math.floor((end - start) / step) + 1
return Array(len).fill().map((_, idx) => start + (idx * step))
}
var result = range(9, 18, 0.83);
console.log(result);
実際のプロジェクトでは range-inclusive
from npm を使用します。後方ステップもサポートしているので、それはクールです。
アンダースコアまたはlo-dashライブラリを強くお勧めします。
http://underscorejs.org/#range
(ほぼ完全に互換性があり、明らかにlodashはより高速に動作しますが、アンダースコアのほうが優れています)
_.range([start], stop, [step])
両方のライブラリには、非常に便利なユーティリティがたくさんあります。
var genArr=(1)['..'](10) //[1,2,3,4,5,6,7,8,9,10]
Number.prototype['..']=function(to,step){
var arr = [],from=this;
while(from <= to){
arr.Push(from++);
}
return arr;
};
http://jsfiddle.net/abdennour/mcpnvsmm/
console.log(
Array.from({length:10},(v,k)=>k+1)
)
私のバージョンのループ;)
var lowEnd = 1;
var highEnd = 25;
var arr = [];
while(lowEnd <= highEnd){
arr.Push(lowEnd++);
}
最速の方法
関数:
var x=function(a,b,c,d){d=[];c=b-a+1;while(c--){d[c]=b--}return d},
theArray=x(lowEnd,highEnd);
または
var arr=[],c=highEnd-lowEnd+1;
while(c--){arr[c]=highEnd--}
編集
読み取り可能なバージョン
var arr = [],
c = highEnd - lowEnd + 1;
while ( c-- ) {
arr[c] = highEnd--
}
デモ
ダウンボター向け
パフォーマンス
http://jsperf.com/for-Push-while-set/2
IEではより速く、firefoxでは3倍速くなります
aipad airでのみforループが少し速くなります。
win8、osx10.8、ubuntu14.04、ipad、ipad air、iPodでテスト済み。
クロム、ff、すなわち、サファリ、モバイルサファリ.
古いループ、つまりforループが最適化されていないブラウザーでのパフォーマンスを確認したいと思います。
function range(j, k) {
return Array
.apply(null, Array((k - j) + 1))
.map(function(_, n){ return n + j; });
}
これはおおよそ同等です
function range(j, k) {
var targetLength = (k - j) + 1;
var a = Array(targetLength);
var b = Array.apply(null, a);
var c = b.map(function(_, n){ return n + j; });
return c;
}
分解する:
var targetLength = (k - j) + 1;
var a = Array(targetLength);
これにより、正しい公称長のスパース行列が作成されます。現在、スパース行列の問題は、正しい公称長さを持っているが、実際の要素を持たないことです。
j = 7, k = 13
console.log(a);
私たちに与えます
Array [ <7 empty slots> ]
それから
var b = Array.apply(null, a);
スパース行列を引数リストとしてArrayコンストラクタに渡します。Arrayコンストラクタは、(実際の)長さtargetLengthの密行列を生成します。ここで、すべての要素は未定義の値を持ちます。最初の引数は、配列コンストラクター関数実行コンテキストの「this」値であり、ここでは役割を果たさないため、nullです。
だから今、
console.log(b);
利回り
Array [ undefined, undefined, undefined, undefined, undefined, undefined, undefined ]
最後に
var c = b.map(function(_, n){ return n + j; });
array.map関数が渡す事実を利用します:1.現在の要素の値と2.現在の要素のインデックスをマップデリゲート/コールバックに。最初の引数は破棄されますが、開始オフセットを調整した後、2番目の引数を使用して正しいシーケンス値を設定できます。
それで
console.log(c);
利回り
Array [ 7, 8, 9, 10, 11, 12, 13 ]
開始が常に終了よりも少ない場合、次のことができます。
function range(start, end) {
var myArray = [];
for (var i = start; i <= end; i += 1) {
myArray.Push(i);
}
return myArray;
};
console.log(range(4, 12)); // → [4, 5, 6, 7, 8, 9, 10, 11, 12]
3番目の引数を使用して、配列を構築するために使用されるステップを変更し、開始が終了よりも大きい場合でも機能させることができるようにしたい場合:
function otherRange(start, end, step) {
otherArray = [];
if (step == undefined) {
step = 1;
};
if (step > 0) {
for (var i = start; i <= end; i += step) {
otherArray.Push(i);
}
} else {
for (var i = start; i >= end; i += step) {
otherArray.Push(i);
}
};
return otherArray;
};
console.log(otherRange(10, 0, -2)); // → [10, 8, 6, 4, 2, 0]
console.log(otherRange(10, 15)); // → [10, 11, 12, 13, 14, 15]
console.log(otherRange(10, 20, 2)); // → [10, 12, 14, 16, 18, 20]
このように、関数は正および負のステップを受け入れ、ステップが指定されていない場合、デフォルトで1になります。
私の5セント:
双方向整数関数の配列。
range(0、5)が[0, 1, 2, 3, 4, 5]
になる場合。
そして、range(5、0)は[5, 4, 3, 2, 1, 0]
になります。
this answerに基づきます。
function range(start, end) {
const isReverse = (start > end);
const targetLength = isReverse ? (start - end) + 1 : (end - start ) + 1;
const arr = new Array(targetLength);
const b = Array.apply(null, arr);
const result = b.map((discard, n) => {
return (isReverse) ? n + end : n + start;
});
return (isReverse) ? result.reverse() : result;
}
追伸実際に使用するには、isFinite()
およびisNaN()
の引数も確認する必要があります。
「開始」番号に到達するまで、「開始」番号を必要な量だけ増分する範囲メソッドを設計できます。この例は、fromがtoよりも大きいか小さいかによって、カウントアップまたはカウントダウンします。
Array.range= function(from, to, step){
if(typeof from== 'number'){
var A= [from];
step= typeof step== 'number'? Math.abs(step):1;
if(from> to){
while((from -= step)>= to) A.Push(from);
}
else{
while((from += step)<= to) A.Push(from);
}
return A;
}
}
10進数でステップしたい場合:Array.range(0,1、.01)浮動小数点の不正確さの値を切り捨てる必要があります。それ以外の場合、0.06の代わりに0.060000000000000005のような数値を返します。
これにより、他のバージョンに多少のオーバーヘッドが追加されますが、整数または小数のステップでは正しく機能します。
Array.range= function(from, to, step, prec){
if(typeof from== 'number'){
var A= [from];
step= typeof step== 'number'? Math.abs(step):1;
if(!prec){
prec= (from+step)%1? String((from+step)%1).length+1:0;
}
if(from> to){
while(+(from -= step).toFixed(prec)>= to) A.Push(+from.toFixed(prec));
}
else{
while(+(from += step).toFixed(prec)<= to) A.Push(+from.toFixed(prec));
}
return A;
}
}
var values = $(this).val().split('-'),
i = +values[0],
l = +values[1],
range = [];
while (i < l) {
range[range.length] = i;
i += 1;
}
range[range.length] = l;
おそらくDRYerでループを実行する方法がありますが、それが基本的な考え方です。
function createNumberArray(lowEnd, highEnd) {
var start = lowEnd;
var array = [start];
while (start < highEnd) {
array.Push(start);
start++;
}
}
http://minifiedjs.com/ を回答リストに追加します:)
コードはアンダースコアなどに似ています:
var l123 = _.range(1, 4); // same as _(1, 2, 3)
var l0123 = _.range(3); // same as _(0, 1, 2)
var neg123 = _.range(-3, 0); // same as _(-3, -2, -1)
var empty = _.range(2,1); // same as _()
ここのドキュメント: http://minifiedjs.com/api/range.html
Minified.jsを使用する理由は、フットプリントが少なく、構文がわかりやすいという問題をすべて解決するからです。私にとっては、1つのフレームワークでjQuery、MustacheJS、Underscore/SugarJSに置き換わるものです。
もちろん、アンダースコアほど人気はありません。これは一部の懸念かもしれません。
ミニファイドは、CC-0(パブリックドメイン)ライセンスを使用してTim Jansenによって利用可能になりました。
function getRange(a,b)
{
ar = new Array();
var y = a - b > 0 ? a - b : b - a;
for (i=1;i<y;i++)
{
ar.Push(i+b);
}
return ar;
}
アンダースコア で解く
data = [];
_.times( highEnd, function( n ){ data.Push( lowEnd ++ ) } );