Am'm în căutarea pentru orice alternative de mai jos pentru a crea o matrice JavaScript care conțin de la 1 la N, unde N este cunoscut doar la runtime.
var foo = [];
for (var i = 1; i <= N; i++) {
foo.push(i);
}
La mine se simte ca și cum acolo ar trebui să fie o modalitate de a face acest lucru fără buclă.
În ES6 folosind Array din() și keys() metode.
Array.from(Array(10).keys())
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Versiune mai scurtă, folosind răspândirea operator.
[...Array(10).keys()]
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Puteți face acest lucru:
var N = 10;
Array.apply(null, {length: N}).map(Number.call, Number)
rezultatul: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
sau cu valori aleatoare:
Array.apply(null, {length: N}).map(Function.call, Math.random)
rezultat: [0.7082694901619107, 0.9572225909214467, 0.8586748542729765, 0.8653848143294454, 0.008339877473190427, 0.9911756622605026, 0.8133423360995948, 0.8377588465809822, 0.5577575915958732, 0.16363654541783035]
În primul rând, rețineți că Numărul.apel(nedefinit, N)este echivalent cu
Numărul(N), care tocmai se întoarce de "N". Am'll folosi de asta mai târziu.
Matrice.aplica(null, [undefined, undefined, undefined])
este echivalent cu `Array(undefined, undefined, undefined), care produce o trei-element de matrice și atribuie "nedefinit" la fiecare element.
Cum poti generaliza ca să N elemente? Ia în considerare modul Array()
lucrări, care merge ceva de genul asta:
function Array() {
if ( arguments.length == 1 &&
'number' === typeof arguments[0] &&
arguments[0] >= 0 && arguments &&
arguments[0] < 1 << 32 ) {
return [ … ]; // array of length arguments[0], generated by native code
}
var a = [];
for (var i = 0; i < arguments.length; i++) {
a.push(arguments[i]);
}
return a;
}
Din ECMAScript 5, Funcția.prototip.aplica(thisArg, argsArray)acceptă, de asemenea, o rață-scris matrice-ca obiect de-al doilea parametru. Dacă vom invoca
Matrice.aplica(null, { lungime: N}), atunci se va executa
function Array() {
var a = [];
for (var i = 0; i < /* arguments.length = */ N; i++) {
a.push(/* arguments[i] = */ undefined);
}
return a;
}
Acum avem o N-element de matrice, fiecare element setat la "nedefinit". Când numim .harta(apel invers, thisArg)
pe ea, fiecare element va fi setat la rezultatul de apel invers.apel(thisArg, element, index, matrice). Prin urmare,
[undefined, undefined, ..., nedefinit].harta(Număr.apel, Număr)ar hartă fiecare element a
(Numărul.apel).apel(Număr, nedefinit, index, matrice), care este același ca Număr.apel(nedefinit, index, matrice), care, după cum am observat mai devreme, se evaluează la "index". Care completează matrice ale căror elemente sunt aceleași ca și indicele lor.
De ce să te chinui din Matrice.aplica(null, {lungime: N})în loc de
Array(N)? La urma urmei, ambele expresii ar rezulta un _N_-element de matrice de elemente nedefinite. Diferența este că în fosta exprimare, fiecare element este în mod explicit _set_ să nedefinit, întrucât, în cele din urmă, fiecare element a fost niciodată stabilit. În conformitate cu documentația de [
.map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map):
callback
e invocat numai pentru indici din matrice care au atribuit valori; nu este invocat pentru indici care au fost șterse sau care nu au fost atribuite valori.
Prin urmare, Matrice(N)
este insuficientă; Array(N).harta(Număr.apel, Număr)
ar duce la o neinitializata matrice de lungime N.
Deoarece această tehnică se bazează pe comportamentul de Funcție.prototip.se aplică()` specificată în ECMAScript 5, se va nu work în pre-ECMAScript 5 browsere, cum ar fi Chrome 14 și Internet Explorer 9.
Array.from({length: 5}, (v, k) => k+1);
// [1,2,3,4,5]
Astfel :
Array.from({length: N}, (v, k) => k+1);
// [1,2,3,...,N]
Din matrice este inițializat cu nedefinit
pe fiecare poziție, valoarea de " v "va fi "nedefinit"
const range = (N) => Array.from({length: N}, (v, k) => k+1) ;
console.log(
range(5)
)
Dacă am obține ceea ce sunt după, vrei o matrice de numere 1..n
că puteți mai târziu bucla prin.
Dacă acest lucru este tot ce ai nevoie, poți face asta în loc?
var foo = new Array(45); // create an empty array with length 45
atunci când doriți să-l folosească... (ne-optimizate, de exemplu)
for(var i = 0; i < foo.length; i++){
document.write('Item: ' + (i + 1) + ' of ' + foo.length + '<br/>');
}
de exemplu, dacă nu't nevoie pentru a magazin nimic în matrice, ai nevoie doar de un recipient de lungimea care te poate repeta peste... acest lucru ar putea fi mai ușor.
Tablouri innascuta de a gestiona lor lungimi. Deoarece acestea sunt parcurse, indexurile pot fi păstrate în memorie și face referire la acel punct. Dacă un indice aleator trebuie să fie cunoscut, indexOf
metodă poate fi utilizată.
Asta a spus, pentru nevoile dumneavoastră poate doriți doar pentru a declara o matrice de o anumită mărime:
var foo = new Array(N); // where N is a positive integer
/* this will create an array of size, N, primarily for memory allocation,
but does not create any defined values
foo.length // size of Array
foo[ Math.floor(foo.length/2) ] = 'value' // places value in the middle of the array
*/
A face uz de răspândire operator (...
) și "cheilor" de metodă, vă permite să creați temporar matrice de dimensiune N pentru a produce indici, și apoi o nouă matrice care poate fi atribuită variabilei:
var foo = [ ...Array(N).keys() ];
Puteți crea mai întâi dimensiunea de matrice ai nevoie, umple-l cu nedefinite și apoi a crea o nouă matrice folosind "harta", care prezintă fiecare element de la index.
var foo = Array(N).fill().map((v,i)=>i);
Acest lucru ar trebui să fie inițializarea la lungimea de dimensiune N și popularea matrice într-o singură trecere.
Array.from({ length: N }, (v, i) => i)
În ES6 puteți face:
Array(N).fill().harta((e,i)=>i+1);
http://jsbin.com/molabiluwa/edit?js,consola
Edit: S-a schimbat Array(45) " cu " Matrice(N)` de când te - 'am actualizat la întrebare.
console.log(
Array(45).fill(0).map((e,i)=>i+1)
);
Folosesc foarte populare Subliniere _.gama metoda
// _.range([start], stop, [step])
_.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); // => []
function range(start, end) {
var foo = [];
for (var i = start; i <= end; i++) {
foo.push(i);
}
return foo;
}
Apoi a sunat de
var foo = range(1, 5);
Nu există nici un built-in pentru a face acest lucru în Javascript, dar's perfect valabil funcția de utilitate pentru a crea dacă aveți nevoie pentru a face mai mult decât o dată.
Edit: În opinia mea, următoarele este o gamă mai bine funcția. Poate doar pentru că am'm părtinitoare de LINQ, dar cred că's mai util în mai multe cazuri. Kilometraj dvs. poate varia.
function range(start, count) {
if(arguments.length == 1) {
count = start;
start = 0;
}
var foo = [];
for (var i = 0; i < count; i++) {
foo.push(start + i);
}
return foo;
}
cel mai rapid mod de a umple o "Matrice" în v8 este:
[...Array(5)].map((_,i) => i);
rezultatul va fi: [0, 1, 2, 3, 4]
Această întrebare are o multime de raspunsuri complicate, dar un simplu o-linie:
[...Array(255).keys()].map(x => x + 1)
De asemenea, deși cele de mai sus este scurt (și elegant) pentru a scrie, cred că ce urmează este un pic mai repede (pentru o lungime maximă de:
127, Int8,
255, Uint8,
32,767, Int16,
65,535, Uint16,
2,147,483,647, Int32,
4,294,967,295, Uint32.
(bazat pe max valori), de asemenea, aici's mai mult pe Tastat Tablouri):
(new Uint8Array(255)).map(($,i) => i + 1);
Deși această soluție este, de asemenea, nu atât de ideală, pentru că se creează două tablouri, și utilizează suplimentar declarație de variabilă "$" (nu sunt sigur orice modalitate de a obține în jurul valorii de faptul că, folosind această metodă). Cred că următoarea soluție este absolut cel mai rapid mod posibil de a face acest lucru:
for(var i = 0, arr = new Uint8Array(255); i < arr.length; i++) arr[i] = i + 1;
Oricând după această declarație este făcută, puteți să utilizați simplu variabilă "arr" în domeniul de aplicare actual;
Dacă doriți să faceți o simplă funcție de se (cu unele de verificare de bază):
function range(min, max) {
min = min && min.constructor == Number ? min : 0;
!(max && max.constructor == Number && max > min) && // boolean statements can also be used with void return types, like a one-line if statement.
((max = min) & (min = 0)); //if there is a "max" argument specified, then first check if its a number and if its graeter than min: if so, stay the same; if not, then consider it as if there is no "max" in the first place, and "max" becomes "min" (and min becomes 0 by default)
for(var i = 0, arr = new (
max < 128 ? Int8Array :
max < 256 ? Uint8Array :
max < 32768 ? Int16Array :
max < 65536 ? Uint16Array :
max < 2147483648 ? Int32Array :
max < 4294967296 ? Uint32Array :
Array
)(max - min); i < arr.length; i++) arr[i] = i + min;
return arr;
}
//and you can loop through it easily using array methods if you want
range(1,11).forEach(x => console.log(x));
//sau daca're folosit pentru pitoni pentru...înpoți face un lucru similar cu
pentru...de` dacă doriți valorile individuale:
pentru(i de gama(2020,2025)) console.log(i);
//or if you really want to use `for..in`, you can, but then you will only be accessing the keys:
for(k in range(25,30)) console.log(k);
console.log(
range(1,128).constructor.name,
range(200).constructor.name,
range(400,900).constructor.name,
range(33333).constructor.name,
range(823, 100000).constructor.name,
range(10,4) // when the "min" argument is greater than the "max", then it just considers it as if there is no "max", and the new max becomes "min", and "min" becomes 0, as if "max" was never even written
);
deci, cu funcția de mai sus, mai sus super-lent "simplu o-linie" devine super-rapid, chiar mai scurte:
range(1,14000);
Puteți folosi acest lucru:
new Array(/*any number which you want*/)
.join().split(',')
.map(function(item, index){ return ++index;})
de exemplu
new Array(10)
.join().split(',')
.map(function(item, index){ return ++index;})
se va crea următoarea matrice:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Dacă se întâmplă să fie folosind d3.js în aplicația dumneavoastră, ca și mine, D3 oferă un helper funcția care face acest lucru pentru tine.
Deci, pentru a obține o gamă de la 0 la 4, l's la fel de ușor ca:
d3.range(5)
[0, 1, 2, 3, 4]
și pentru a obține o gamă de la 1 la 5, după cum au fost solicitante:
d3.range(1, 5+1)
[1, 2, 3, 4, 5]
Check out acest tutorial pentru mai multe informații.
Aceasta este, probabil, cel mai rapid mod de a genera o matrice de numere
Mai scurt
var a=[],b=N;while(b--)a[b]=b+1;
Inline
var arr=(function(a,b){while(a--)b[a]=a;return b})(10,[]);
//arr=[0,1,2,3,4,5,6,7,8,9]
Dacă doriți să începeți de la 1
var arr=(function(a,b){while(a--)b[a]=a+1;return b})(10,[]);
//arr=[1,2,3,4,5,6,7,8,9,10]
Vreau o funcție?
function range(a,b,c){c=[];while(a--)c[a]=a+b;return c}; //length,start,placeholder
var arr=range(10,5);
//arr=[5,6,7,8,9,10,11,12,13,14]
De CE?
în timp ce
este cel mai rapid buclă
Stabilirea directă este mai rapid decât "push"
[]
este mai rapid decât new Array(10)
l's scurt... uite primul cod. apoi uita-te la toate celelalte funcții de aici.
Dacă vă place poate't trăi fără pentru
for(var a=[],b=7;b>0;a[--b]=b+1); //a=[1,2,3,4,5,6,7]
sau
for(var a=[],b=7;b--;a[b]=b+1); //a=[1,2,3,4,5,6,7]
Folosind ES2015/ES6 răspândit operator
[...Array(10)].map((_, i) => i + 1)
console.log([...Array(10)].map((_, i) => i + 1))
Dacă utilizați lodash, puteți utiliza _.range:
_.gama([start=0], end, [pas=1])
Creează o matrice de numere (pozitive și/sau negative) progresează de la început până la, dar nu inclusiv, end. Un pas de -1 este folosit dacă o început negativ este specificat fără un scop sau pas. Dacă sfârșitul nu este specificat, se's set pentru a începe cu start apoi setat la 0.
Exemple:
_.range(4);
// ➜ [0, 1, 2, 3]
_.range(-4);
// ➜ [0, -1, -2, -3]
_.range(1, 5);
// ➜ [1, 2, 3, 4]
_.range(0, 20, 5);
// ➜ [0, 5, 10, 15]
_.range(0, -4, -1);
// ➜ [0, -1, -2, -3]
_.range(1, 4, 0);
// ➜ [1, 1, 1]
_.range(0);
// ➜ []
Final de raport de Sinteză .. Drrruummm Rolll -
Acest lucru este cel mai scurt cod pentru a genera o Matrice de dimensiune N (10) fără a utiliza ES6. Cocco's versiunea de mai sus este aproape, dar nu cel mai scurt.
(function(n){for(a=[];n--;a[n]=n+1);return a})(10)
Dar câștigătorul de necontestat din acest Cod golf(competiție pentru a rezolva o anumită problemă în cel mai mic octeți de cod sursă) este Niko Suedeză . Folosind Matrice Constructor și ES6 răspândit operator . (De cele mai multe ES6 sintaxa este valabil mașina de scris, dar următoarele nu este. Astfel încât să fie judicioasă în timp ce folosind-o)
[...Array(10).keys()]
Nu există un alt mod în ES6, folosind Matrice.de care are 2 argumente, în primul rând este un arrayLike (în acest caz, un obiect cu o lungime de proprietate), și cea de-a doua este o funcție de cartografiere (în acest caz, vom hartă elementul de index)
Array.from({length:10}, (v,i) => i)
acest lucru este mai scurtă și poate fi folosit pentru alte secvențe ca generarea de numere
Array.from({length:10}, (v,i) => i*2)
De asemenea, acesta are o performanță mai bună decât cele mai multe alte moduri, deoarece numai bucle dată prin matrice. Verificați snippit pentru unele comparații
// open the dev console to see results
count = 100000
console.time("from object")
for (let i = 0; i<count; i++) {
range = Array.from({length:10}, (v,i) => i )
}
console.timeEnd("from object")
console.time("from keys")
for (let i =0; i<count; i++) {
range = Array.from(Array(10).keys())
}
console.timeEnd("from keys")
console.time("apply")
for (let i = 0; i<count; i++) {
range = Array.apply(null, { length: 10 }).map(function(element, index) { return index; })
}
console.timeEnd("apply")