SORU
19 EYLÜL 2010, Pazar


JavaScript bir dizi 1...N içeren oluşturun

Aşağıda JavaScript bir dizi N sadece çalışma zamanında bilinen, 1 ile N içeren oluşturmak için başka alternatif arıyorum.

var foo = [];

for (var i = 1; i <= N; i  ) {
   foo.push(i);
}

Bana döngü olmadan bunu yapmanın bir yolu olmalı gibi geliyor.

CEVAP
19 Kasım 2013, Salı


Bunu yapabilirsiniz:

var N = 10; 
Array.apply(null, {length: N}).map(Number.call, Number)

sonuç: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

ya rasgele değerleri ile

Array.apply(null, {length: N}).map(Function.call, Math.random)

sonuç: [0.7082694901619107, 0.9572225909214467, 0.8586748542729765, 0.8653848143294454, 0.008339877473190427, 0.9911756622605026, 0.8133423360995948, 0.8377588465809822, 0.5577575915958732, 0.16363654541783035]

Açıklama

İlk, Number.call(undefined, N) sadece N döner Number(N) eşdeğer olduğunu unutmayın. Bu gerçeği daha sonra kullanacağız.

Array.apply(null, [undefined, undefined, undefined]) üç öğeli bir dizi üretir ve her öğe için undefined atar Array(undefined, undefined, undefined), eşdeğerdir.

Nasıl böyle bir genelleme yapabilirsinNelemanlar? Böyle bir şey gider Array() nasıl çalıştığını düşünün:

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;
}

*, *16 Since ECMAScript 5 da ikinci parametre olarak ördek-yazılı dizi gibi bir nesne kabul eder. Biz Array.apply(null, { length: N }) ardından çağırmak çalıştırır

function Array() {
    var a = [];
    for (var i = 0; i < /* arguments.length = */ N; i  ) {
        a.push(/* arguments[i] = */ undefined);
    }
    return a;
}

Şimdi bir varN-element dizisi, her elemanı ile undefined ayarlayın. Üzerinde .map(callback, thisArg) dediğimiz zaman, her öğe callback.call(thisArg, element, index, array) sonuç olarak ayarlanır. Bu nedenle, [undefined, undefined, …, undefined].map(Number.call, Number) daha önce gördüğümüz gibi, 25 ** veren Number.call(undefined, index, array), aynı (Number.call).call(Number, undefined, index, array) her öğe göster. O kendi dizin olarak aynı olan dizi tamamlar.

Neden Array.apply(null, {length: N}) sorun yerine Array(N) devam mı? Sonuçta, her iki ifade de bir sonuç olurduNtanımsız elemanlar eleman dizi. Fark, eski ifadesinde, her öğe açıkça olmasıdırayarlayınikincisi ise tanımsız için, her öğe asla kuruldu. .map(): belgelere göre

callback değerleri atanmış olan dizinin dizinler için çağrılır; silinmiş olan veya hiç atanan değerleri olan dizinler için çağrılır.

Bu nedenle, Array(N) yeterli uzunlukta başlatılmamış bir dizi neden olacaktırN.

Uyumluluk

Bu tekniği Function.prototype.apply() davranış ECMA belirtilen dayanır bu yana 5, 37* *pre-ECMA Chrome 14 ve İnternet gibi 5 tarayıcılar Explorer 9'da olacak.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Juan Carlos Candela Bordera

    Juan Carlos

    4 Mart 2009
  • Troy Hunt

    Troy Hunt

    29 EYLÜL 2011
  • Vladimir Jenko

    Vladimir Jen

    1 Mart 2010