සපයන ලද සීමාවන් තුළ පරාසයක් ජනනය කිරීම සඳහා ජාවාස්ක්‍රිප්ටයට “පරාසය ()” වැනි ක්‍රමයක් තිබේද?


943

PHP හි, ඔබට කළ හැකිය ...

range(1, 3); // Array(1, 2, 3)
range("A", "C"); // Array("A", "B", "C")

එනම්, ඉහළ සහ පහළ සීමාවන් පසුකරමින් ඔබට සංඛ්‍යා හෝ අක්ෂර පරාසයක් ලබා ගැනීමට ඉඩ සලසන ශ්‍රිතයක් ඇත.

මේ සඳහා ස්වදේශීයව ජාවාස්ක්‍රිප්ට් සඳහා සාදන ලද යමක් තිබේද? එසේ නොවේ නම්, මම එය ක්‍රියාත්මක කරන්නේ කෙසේද?


1
Prototype.js හි $Rක්‍රියාකාරීත්වය ඇත, නමුත් ඒ හැර මම එසේ සිතන්නේ නැත.
යී ජියැන්ග්

මෙම (අදාළ) ප්‍රශ්නයට විශිෂ්ට පිළිතුරු කිහිපයක් ඇත: stackoverflow.com/questions/6299500/…
btk

Array.from("ABC") //['A', 'B', 'C']ප්‍රශ්නයේ දෙවන කොටස සඳහා මට සොයාගත හැකි ආසන්නතම දේ මෙයයි.
ඇන්ඩ rew_1510

@ ඇන්ඩ rew_1510 ඔබට split("")එහි ද භාවිතා කළ හැකිය
ඇලෙක්ස්

1
පෙම්වතා බැඳීම ශුන්‍ය වන විට මෙම ඔනලයිනර්:Array.apply(null, { length: 10 }).map(eval.call, Number)
csharpfolk

Answers:


1616

අංක

[...Array(5).keys()];
 => [0, 1, 2, 3, 4]

අක්ෂර පුනරාවර්තනය

String.fromCharCode(...[...Array('D'.charCodeAt(0) - 'A'.charCodeAt(0) + 1).keys()].map(i => i + 'A'.charCodeAt(0)));
 => "ABCD"

අනුකරණය

for (const x of Array(5).keys()) {
  console.log(x, String.fromCharCode('A'.charCodeAt(0) + x));
}
 => 0,"A" 1,"B" 2,"C" 3,"D" 4,"E"

කාර්යයන් ලෙස

function range(size, startAt = 0) {
    return [...Array(size).keys()].map(i => i + startAt);
}

function characterRange(startChar, endChar) {
    return String.fromCharCode(...range(endChar.charCodeAt(0) -
            startChar.charCodeAt(0), startChar.charCodeAt(0)))
}

ටයිප් කළ කාර්යයන් ලෙස

function range(size:number, startAt:number = 0):ReadonlyArray<number> {
    return [...Array(size).keys()].map(i => i + startAt);
}

function characterRange(startChar:string, endChar:string):ReadonlyArray<string> {
    return String.fromCharCode(...range(endChar.charCodeAt(0) -
            startChar.charCodeAt(0), startChar.charCodeAt(0)))
}

lodash.js _.range()ශ්‍රිතය

_.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]
String.fromCharCode(..._.range('A'.charCodeAt(0), 'D'.charCodeAt(0) + 1));
 => "ABCD"

පුස්තකාලයක් නොමැති පැරණි එස් 6 නොවන බ්‍රව්සර්:

Array.apply(null, Array(5)).map(function (_, i) {return i;});
 => [0, 1, 2, 3, 4]

console.log([...Array(5).keys()]);

(නිල්ස් පීටර්සෝන් සහ වෙනත් විචාරකයින්ට ES6 ණය)


74
මන්ද එය ඕනෑම තැනක ප්‍රයෝජනවත් නම් එය බොහෝ විට JS හි ප්‍රයෝජනවත් වේ. (JS ක්රියාකාරී වැඩසටහන් වර්ගය දේවල්, පරාසයක් (0 ප්රකාශයක් ප්රයෝජන ගත හැකි වන කළ හැකි සමහර semirare නඩුවේ ප්රයෝජනවත් විය හැකිය සහ වෙනත් හේතු දහසක්) ඒ.
Lodewijk

5
හුදෙක් භාවිතා කිරීම සාර්ථක නොවන්නේ මන්දැයි කිසියම් අදහසක් (new Array(5)).map(function (value, index) { return index; })තිබේද? මෙය [undefined × 5]මට Chrome DevTools හි නැවත පැමිණේ .
ලුවිස්

12
Ew ලුවිස් ඒ සමඟ අර්ථ දක්වා ඇති අරාවකට හිස් තව් ඇති බැවින් එය map()හෝ එහි මිතුරෙකු සමඟ නැවත නොකෙරේ .
ඇලෙක්ස්

69
Array.from (Array (5) .keys ())
nils petersohn

19
Array(5).fill()
mappable

373

අංක සඳහා ඔබට ES6 භාවිතා කළ හැකිය Array.from(), එය IE හැර මේ දිනවල සෑම දෙයක්ම ක්‍රියාත්මක වේ :

කෙටි අනුවාදය:

Array.from({length: 20}, (x, i) => i);

දිගු අනුවාදය:

Array.from(new Array(20), (x, i) => i);​​​​​​

එය ඇතුළත් 0 සිට 19 දක්වා අරාවක් නිර්මාණය කරයි. මෙය තවදුරටත් මෙම ආකාර වලින් කෙටි කළ හැකිය:

Array.from(Array(20).keys());
// or
[...Array(20).keys()];

පහළ සහ ඉහළ සීමාවන් ද නියම කළ හැකිය, උදාහරණයක් ලෙස:

Array.from(new Array(20), (x, i) => i + *lowerBound*);

මෙය වඩාත් විස්තරාත්මකව විස්තර කරන ලිපියක්: http://www.2ality.com/2014/05/es6-array-methods.html


57
පළමු උදාහරණය සරල කළ හැකිය [... අරාව (20) .කයිස් ()]
ඩෙලපූයිට්

29
Array.from()ක්‍රමයට වඩා තරමක් සංක්ෂිප්ත සහ දෙකටම වඩා වේගවත්:Array(20).fill().map((_, i) => i)
ස්ටූ කොක්ස්

2
E ඩෙලපූයිට් නියමයි! ඔබ එයට වෙනම පිළිතුරක් දිය යුතු අතර මම ඒ සඳහා ඡන්දය දෙන්නෙමි! එය ද මෙම අනුපිටපතට පරිපූර්ණ පිළිතුරකි .
ජිබ්

9
E ඩෙලපූයිට් @ ජිබ් සහ මෙයද:Array.from({length: end - start}, (v, k) => k + start)
ආදිත්‍ය සිං

1
c icc97 ඔව්, ජාවාස්ක්‍රිප්ට් හි ශ්‍රිත තර්කයක් මඟ හැරීම සමාන යැයි අර්ථ දැක්වුවද, ලින්ටර් පැමිණිලි කළ හැකිය undefined, එබැවින් fill()(කිසිදු තර්කයක් නොමැතිව) වැරදිය . පිරවුම් අගය එම විසඳුමෙහි භාවිතා නොවේ, එබැවින් ඔබ කැමති නම් fill(0)අක්ෂර කිහිපයක් සුරැකීමට භාවිතා කළ හැකිය .
ස්ටු කොක්ස්

137

මගේ නව ප්‍රියතම පෝරමය ( ES2015 )

Array(10).fill(1).map((x, y) => x + y)

ඔබට stepපරාමිතියක් සහිත ශ්‍රිතයක් අවශ්‍ය නම් :

const range = (start, stop, step = 1) =>
  Array(Math.ceil((stop - start) / step)).fill(start).map((x, y) => x + y * step)

5
ඉඩ පරාසය = (ආරම්භ නැවතුම්, පළමු පියවර = 1) => Array (stop - ආරම්භයක්) .fill (ආරම්භක) .map ((x, y) => x + y * පියවර)
rodfersou

4
@rodfersou FYI: ඔබේ උදාහරණය වැරදියි. stopඇත්ත වශයෙන්ම නැවතුම් / අවසන් ස්ථානය නොව ගණන් / දුර වේ. (වරදක් නැත,
යතුරු ලියනය

4
ව්‍යාකූලත්වයට - එෆ් ලෙක්චාස්ගේ අදහස් දැක්වීමෙන් පසු රොඩ්ෆර්සෝගේ සංස්කරණය හේතුවෙන් ඔහුගේ කේතය දැන් නිවැරදි ය.
ඊද්‍රා

1
ඔබ වෙත ගමන් තර්කය Array(Math.ceil((stop - start) / step) + 1), අවශ්යයි +1ඇත්තටම පැතිරෙයි php ගේ "ඇතුලත්" හැසිරීම, අවසානයේ දී.
ජොහාන් ඩෙට්මාර්

3
ජාවාස්ක්‍රිප්ට් ශ්‍රිතයක සම්පූර්ණ ප්‍රශ්නයට සත්‍ය වශයෙන්ම පිළිතුරු සපයන ඉහළම පිළිතුර මෙයයි range. දැනට මෙයට ඉහළින් ඇති අනෙක් සියල්ලම (ලොඩාෂ් හැර _.range) ආරම්භක, නැවතුම් සහ පියවර සමඟ සත්‍ය පරාස ශ්‍රිතයකට වඩා මූලික අනුකාරක ක්‍රියාත්මක කරයි
icc97

101

මෙන්න මගේ ශත 2:

function range(start, count) {
  return Array.apply(0, Array(count))
    .map((element, index) => index + start);
}

1
ඉහළ පෙළේ කාර්යයන් විශිෂ්ට ලෙස භාවිතා කිරීම.
ෆර්සාඩ් වයිසඩ්

7
මෙය ඇත්ත වශයෙන්ම වැරදියි, මන්ද ප්‍රශ්නය ආරම්භක සහ අවසාන අගයන් ඉල්ලා සිටින බැවිනි. ආරම්භ කිරීම සහ ගණන් කිරීම / දුර නොවේ.
ජේම්ස් රොබී

75

එය අක්ෂර සහ සංඛ්‍යා සඳහා ක්‍රියා කරයි, විකල්ප පියවරක් සමඟ ඉදිරියට හෝ පසුපසට යයි.

var range = function(start, end, step) {
    var range = [];
    var typeofStart = typeof start;
    var typeofEnd = typeof end;

    if (step === 0) {
        throw TypeError("Step cannot be zero.");
    }

    if (typeofStart == "undefined" || typeofEnd == "undefined") {
        throw TypeError("Must pass start and end arguments.");
    } else if (typeofStart != typeofEnd) {
        throw TypeError("Start and end arguments must be of same type.");
    }

    typeof step == "undefined" && (step = 1);

    if (end < start) {
        step = -step;
    }

    if (typeofStart == "number") {

        while (step > 0 ? end >= start : end <= start) {
            range.push(start);
            start += step;
        }

    } else if (typeofStart == "string") {

        if (start.length != 1 || end.length != 1) {
            throw TypeError("Only strings with one character are supported.");
        }

        start = start.charCodeAt(0);
        end = end.charCodeAt(0);

        while (step > 0 ? end >= start : end <= start) {
            range.push(String.fromCharCode(start));
            start += step;
        }

    } else {
        throw TypeError("Only string and number types are supported");
    }

    return range;

}

jsFiddle .

ස්වදේශීය වර්ග වැඩි කිරීම ඔබේ දෙයක් නම්, එය පවරන්න Array.range.


55

සරල පරාස ශ්‍රිතය:

function range(start, stop, step) {
    var a = [start], b = start;
    while (b < stop) {
        a.push(b += step || 1);
    }
    return a;
}

සංස්ථාගත කිරීම සඳහා වූ මෙම BitInt දත්ත ටයිප් සියලු විචල්යයන් එකම බව සහතික, සමහර චෙක්පත් ඇතුළත් කළ හැකිය typeof start:

function range(start, stop, step) {
    var a = [start], b = start;
    if (typeof start == 'bigint') {
        stop = BigInt(stop)
        step = step? BigInt(step): 1n;
    } else
        step = step || 1;
    while (b < stop) {
        a.push(b += step);
    }
    return a;
}

stopඋදා. range(0,5,2)මගින් අර්ථ දක්වා ඇති අගයන් ඉවත් කිරීමට ඇතුළත් 6විය යුතුය.

function range(start, stop, step) {
    var a = [start], b = start;
    while (b < stop) {
        a.push(b += step || 1);
    }
    return (b > stop) ? a.slice(0,-1) : a;
}

3
භාවිතා කළ හැකි සහ කියවිය හැකි සඳහා ප්ලස් UNO. මම දීර් time කාලයක් තිස්සේ දැක ඇති හොඳම කේත ස්නිපටය.
මොන්ස්ටෝ

1
විට මෙම වැඩ කරන්නේ නැහැ step != 1එම, whileතත්ත්වය සැලකිල්ලට ගත යුතු stepගිණුමට. පෙරනිමි stepඅගයක් සහිත මගේ යාවත්කාලීන කළ අනුවාදය : ශ්‍රිත පරාසය (ආරම්භය, නැවැත්වීම, පියවර) {පියවර = පියවර || 1 var a = [ආරම්භය], b = ආරම්භය; අතර ((b + step) <stop) {console.log ("b:" + b + ". a:" + a + "."); b + = පියවර; a.push (ආ); } ආපසු a; }
daveharris

avedaveharris මම පෙරනිමි පියවරක් එකතු කළෙමි , (step || 1).
පොලිවර්ල් මහතා

39

හරි, ජාවාස්ක්‍රිප්ට් හි අපට PHPrange() වැනි ශ්‍රිතයක් නොමැත , එබැවින් අපට ශ්‍රිතය සෑදිය යුතුය, එය ඉතා පහසු දෙයකි, මම ඔබ වෙනුවෙන් එක්-පේළි ශ්‍රිත කිහිපයක් ලියා ඒවා අංක සහ අක්ෂර සඳහා පහත පරිදි වෙන් කරමි:

අංක සඳහා :

function numberRange (start, end) {
  return new Array(end - start).fill().map((d, i) => i + start);
}

එය මෙසේ අමතන්න:

numberRange(5, 10); //[5, 6, 7, 8, 9]

හෝඩිය සඳහා :

function alphabetRange (start, end) {
  return new Array(end.charCodeAt(0) - start.charCodeAt(0)).fill().map((d, i) => String.fromCharCode(i + start.charCodeAt(0)));
}

එය මෙසේ අමතන්න:

alphabetRange('c', 'h'); //["c", "d", "e", "f", "g"]

2
මෙම කාර්යයන්හි එක් එක් දෝෂයන් ඇති බව මම සිතමි. විය යුතුය Array(end - start + 1), සහ Array(end.charCodeAt(0) - start.charCodeAt(0) + 1).
පෝල්

39
Array.range = function(a, b, step){
    var A = [];
    if(typeof a == 'number'){
        A[0] = a;
        step = step || 1;
        while(a+step <= b){
            A[A.length]= a+= step;
        }
    }
    else {
        var s = 'abcdefghijklmnopqrstuvwxyz';
        if(a === a.toUpperCase()){
            b = b.toUpperCase();
            s = s.toUpperCase();
        }
        s = s.substring(s.indexOf(a), s.indexOf(b)+ 1);
        A = s.split('');        
    }
    return A;
}
    
    
Array.range(0,10);
// [0,1,2,3,4,5,6,7,8,9,10]
    
Array.range(-100,100,20);
// [-100,-80,-60,-40,-20,0,20,40,60,80,100]
    
Array.range('A','F');
// ['A','B','C','D','E','F')
    
Array.range('m','r');
// ['m','n','o','p','q','r']

ඔබ ඇත්ත වශයෙන්ම Arrayමූලාකෘතියට ජෙරී-රිග් ක්‍රම නොකළ යුතුය .
connectyourcharger

මෙම ක්‍රමය ක්‍රියාත්මක වන්නේ පූර්ණ සංඛ්‍යා හා අක්ෂර සමඟ පමණි. පරාමිතීන් ශුන්‍ය, නිර්වචනය නොකළ, NaN, බූලියන්, අරාව, වස්තුව යනාදිය නම්, මෙම ක්‍රමය මඟින් පහත දැක්වෙන දෝෂය ලබා දෙයි : undefined method toUpperCase to etc!
වික්ටර්

`` `if (යතුරු ලියනය කරන්න! == 'අංකය' && සිට යතුරු ලියනය කරන්න! අංකය '&& == කිරීමට typeof!' string ') {නව TypeError විසි (' පළමු පරාමිතිය අංකය හෝ චරිතයක් 'විය යුතුය)}' '' '
වික්ටර්

24

උපක්‍රමය කිරීමට පහසු කාර්යයක්, පහත කේත ස්නිපටය ධාවනය කරන්න

function range(start, end, step, offset) {
  
  var len = (Math.abs(end - start) + ((offset || 0) * 2)) / (step || 1) + 1;
  var direction = start < end ? 1 : -1;
  var startingPoint = start - (direction * (offset || 0));
  var stepSize = direction * (step || 1);
  
  return Array(len).fill(0).map(function(_, index) {
    return startingPoint + (stepSize * index);
  });
  
}

console.log('range(1, 5)=> ' + range(1, 5));
console.log('range(5, 1)=> ' + range(5, 1));
console.log('range(5, 5)=> ' + range(5, 5));
console.log('range(-5, 5)=> ' + range(-5, 5));
console.log('range(-10, 5, 5)=> ' + range(-10, 5, 5));
console.log('range(1, 5, 1, 2)=> ' + range(1, 5, 1, 2));

මෙන්න එය භාවිතා කරන ආකාරය

පරාසය (ආරම්භය, අවසානය, පියවර = 1, ඕෆ්සෙට් = 0);

  • ඇතුළත් - ඉදිරියට range(5,10) // [5, 6, 7, 8, 9, 10]
  • ඇතුළත් - පසුගාමී range(10,5) // [10, 9, 8, 7, 6, 5]
  • පියවර - පසුපසට range(10,2,2) // [10, 8, 6, 4, 2]
  • සුවිශේෂී - ඉදිරියට range(5,10,0,-1) // [6, 7, 8, 9] not 5,10 themselves
  • ඕෆ්සෙට් - පුළුල් කරන්න range(5,10,0,1) // [4, 5, 6, 7, 8, 9, 10, 11]
  • ඕෆ්සෙට් - හැකිලීම range(5,10,0,-2) // [7, 8]
  • පියවර - පුළුල් කරන්න range(10,0,2,2) // [12, 10, 8, 6, 4, 2, 0, -2]

ඔබට එය ප්‍රයෝජනවත් වේ යැයි සිතමි.


මෙන්න එය ක්‍රියාත්මක වන ආකාරයයි.

මූලික වශයෙන් මම පළමුව ප්‍රති ar ලයක් ලෙස ඇති අරාවෙහි දිග ගණනය කර එම දිගට ශුන්‍ය පිරවූ අරාවක් සාදන්න, ඉන්පසු අවශ්‍ය අගයන්ගෙන් එය පුරවන්න

  • (step || 1)=> තවද මේ හා සමාන වෙනත් අය අදහස් කරන්නේ එහි වටිනාකම භාවිතා කරන stepඅතර එය ලබා දී නොමැති නම් ඒ 1වෙනුවට භාවිතා කරන්න
  • අපි ආරම්භ කරන්නේ ප්‍රති result ල අරාවෙහි දිග ගණනය කිරීමෙන් (Math.abs(end - start) + ((offset || 0) * 2)) / (step || 1) + 1)එය වඩාත් සරල ලෙස භාවිතා කිරීමෙනි (වෙනස * දිශාව / පියවර යන දෙකෙහිම ඕෆ්සෙට්)
  • දිග ලබා ගැනීමෙන් පසුව, අපි මෙහි චෙක් භාවිතා කර ආරම්භක අගයන් සහිත හිස් අරාවක් සාදන්නෙමුnew Array(length).fill(0);
  • දැන් අපට [0,0,0,..]අවශ්‍ය දිගට අරාවක් තිබේ. අපි එය සිතියම් ගත කර භාවිතා කිරීමෙන් අපට අවශ්‍ය අගයන් සමඟ නව අරාවක් ලබා දෙන්නෙමුArray.map(function() {})
  • var direction = start < end ? 1 : 0;නිසැකවම අපට පසුපසට යා යුතු startප්‍රමාණයට වඩා කුඩා නොවේ නම් end. මම අදහස් කළේ 0 සිට 5 දක්වා හෝ අනෙක් අතට
  • සෑම පුනරාවර්තනයකදීම startingPoint+ stepSize* indexඅපට අවශ්‍ය අගය ලබා දෙයි

8
හැන්ඩි, නිසැකවම. සරල? වෙනස් වීමට මා බැගාපත් විය; නොසලකා ඔබ එය එක් ලයිනර් එකක් බවට පත් කරයි. පයිතන් සිට පැමිණීම මෙය කම්පනයකි.
පැස්කල් වී කූටන්

Asc පැස්කල්ව් කූටන්, ඔව්, මම අනුමාන කරන පයිතන් වැනි ක්‍රමවේදයක් තිබුනේ නම් එය ඉතා හොඳ වනු ඇත, නමුත් මෙය මට පැමිණිය හැකි සරලම ක්‍රමයයි. එය මගේ ව්‍යාපෘති වලදී ප්‍රයෝජනවත් බව ඔප්පු වී ඇත.
azerafati

ඒ වගේ වේදනාකාරී සංකීර්ණ කේත ස්නිපටයක් පළ කිරීම, විශේෂයෙන් එක් ලයිනර් එකක් ලෙස සහ එය ක්‍රියා කරන ආකාරය පිළිබඳ පැහැදිලි කිරීමක් නොමැතිව? හොඳ SO පිළිතුරක දුර්වල උදාහරණය, එය "ක්‍රියාත්මක වේද" යන්න නොසලකා.
මැඩ්බ්‍රේක්ස්

1
Ad මැඩ්බ්‍රේක්ස්, ඔව් ඔබ හරි. මම එක ලයිනර් එකක් කරන්න බොළඳයි. සෑම කෙනෙකුටම ඉක්මන් හා පහසු විසඳුමක් ලබා දීමට අවශ්‍ය විය
azerafati

22
var range = (l,r) => new Array(r - l).fill().map((_,k) => k + l);

iknikkwong, _මෙය සිතියම්ගත කිරීමේ ඇමතුමේ ඇති තර්කයේ නමකි. ඔබ දන්නවා, සමහර භාෂාවලින් ඔබ _විචල්‍යය භාවිතා නොකරන බව පෙන්වා දීමට නමක් ලෙස භාවිතා කරයි.
ක්ලෙසන්

මෙහි දී, _තර්ක හරහා සම්මත නොවේ range. ඇයි නැත්තේ?
nikk wong

2
ඉතා පිළිවෙලට! කෙසේ වෙතත්, එය කිසිදු IE හෝ ඔපෙරා මත ක්‍රියා නොකරන බව සැලකිල්ලට ගැනීම වැදගත්ය.
රෆායෙල් සේවියර්

5
මෙම පිළිතුර SO සඳහා දුර්වල සුදුසුකමක් වන බැවින් පැහැදිලි කිරීම අවශ්‍ය වේ.
මැඩ්බ්‍රේක්ස්

@RafaelXavier IE සමඟ Array.fill () polyfill
mwag

20

--- යාවත්කාලීන කරන්න (සරල කිරීම සඳහා @lokhmakov ට ස්තූතියි) ---

ES6 උත්පාදක යන්ත්ර භාවිතා කරන තවත් අනුවාදයක් ( ES6 උත්පාදක යන්ත්ර සමඟ විශිෂ්ට පාවුලෝ මොරෙට්ටි පිළිතුර බලන්න ):

const RANGE = (x,y) => Array.from((function*(){
  while (x <= y) yield x++;
})());

console.log(RANGE(3,7));  // [ 3, 4, 5, 6, 7 ]

නැතහොත්, අපට අවශ්‍ය වන්නේ එය නැවත ලබා ගත හැකි නම් පමණි:

const RANGE_ITER = (x,y) => (function*(){
  while (x <= y) yield x++;
})();

for (let n of RANGE_ITER(3,7)){
  console.log(n);
}

// 3
// 4
// 5
// 6
// 7

--- සාමාන්‍ය කේතය වූයේ: ---

const RANGE = (a,b) => Array.from((function*(x,y){
  while (x <= y) yield x++;
})(a,b));

සහ

const RANGE_ITER = (a,b) => (function*(x,y){
  while (x <= y) yield x++;
})(a,b);

2
යන්තම් const range = (x, y) => Array.from(function* () { while (x <= y) yield x++; }())
ලොක්මාකොව්

@lokhmakov ඔව්, ඔබ හරි. ඔබට ස්තුතියි! මගේ පිළිතුරේ ඔබේ කේතය යොදන්න.
Hero Qu

19

Harmony පැතිරුම් ක්‍රියාකරු සහ ඊතල කාර්යයන් භාවිතා කිරීම:

var range = (start, end) => [...Array(end - start + 1)].map((_, i) => start + i);

උදාහරණයක්:

range(10, 15);
[ 10, 11, 12, 13, 14, 15 ]

ඒක තමයි හොඳම පිළිතුර!
හෙන්රි එච්.

1
වේගවත්ම නොවේ.
mjwrazor

මෙම නඩුවේ '_' සංකේතය අවධාරනය කරන්නේ කුමක්ද?
ඔලේ බෙරෙහෝව්ස්කි

LeOlehBerehovskyi එයින් අදහස් කරන්නේ ඔබ සැබවින්ම භාවිතා කිරීමට අදහස් නොකරන ලැම්බඩා ශ්‍රිත පරාමිතියකි. භාවිතයට නොගත් විචල්‍යයන් ගැන අනතුරු අඟවන ලින්ටරයක් ​​එය නොසලකා හැරිය යුතුය.
මීකා සොල්ටු

15

විවිධ පරාස කාර්යයන් පිළිබඳව යම් පර්යේෂණ කළාද? මෙම කාර්යයන් සිදු කිරීම සඳහා විවිධ ක්‍රම පිළිබඳ jsperf සංසන්දනය පරීක්ෂා කරන්න. නිසැකවම පරිපූර්ණ හෝ පරිපූර්ණ ලැයිස්තුවක් නොවේ, නමුත් උදව් කළ යුතුය :)

ජයග්රාහකයා වන්නේ...

function range(lowEnd,highEnd){
    var arr = [],
    c = highEnd - lowEnd + 1;
    while ( c-- ) {
        arr[c] = highEnd--
    }
    return arr;
}
range(0,31);

තාක්‍ෂණිකව එය ෆයර්ෆොක්ස් හි වේගවත්ම නොවේ, නමුත් ක්‍රෝම් හි පිස්සු වේග වෙනස (ඉම්හෝ) ඒ සඳහා උපකාරී වේ.

ෆයර්ෆොක්ස් වලට වඩා මෙම අරා ක්‍රියාකාරිත්වයන් සමඟ ක්‍රෝම් කොතරම් වේගවත්ද යන්න සිත්ගන්නා කරුණකි. Chrome අවම වශයෙන් 4 හෝ 5 ගුණයක් වේගවත් වේ.


පියවර ප්‍රමාණයේ පරාමිතියක් ඇතුළත් පරාසයේ ශ්‍රිත සමඟ මෙය සංසන්දනය කර ඇති බව සලකන්න
ද්විමය ෆන්ට්

14

ඔබට lodash හෝ Undescore.js භාවිතා කළ හැකිය range:

var range = require('lodash/range')
range(10)
// -> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

විකල්පයක් ලෙස, ඔබට අවශ්‍ය වන්නේ අඛණ්ඩව පූර්ණ සංඛ්‍යා පරාසයක් පමණක් නම් ඔබට එවැනි දෙයක් කළ හැකිය:

Array.apply(undefined, { length: 10 }).map(Number.call, Number)
// -> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

ES6 හි උත්පාදක යන්ත්රrange සමඟ ක්රියාත්මක කළ හැකිය :

function* range(start=0, end=null, step=1) {
  if (end == null) {
    end = start;
    start = 0;
  }

  for (let i=start; i < end; i+=step) {
    yield i;
  }
}

විශාල අනුක්‍රමයන් පුනරාවර්තනය කිරීමේදී මෙම ක්‍රියාවට නැංවීම මතකය සුරකිනු ඇත, මන්ද එයට සියලු අගයන් අරාව තුළට ගෙන ඒමට අවශ්‍ය නොවන බැවිනි:

for (let i of range(1, oneZillion)) {
  console.log(i);
}

ES6 කොටස දැන් මෙම ප්‍රශ්නයට නිවැරදි පිළිතුරයි. වෙනත් පිළිතුරු වලින් ආවරණය වන අනෙක් කොටස් ඉවත් කිරීමට මම නිර්දේශ කරමි.
joews

x = පරාසය (1, 10); // {} x; // {} // හිස් සිතියමක් මෙන් පෙනේ WTF!?! x.next (). අගය; // හරි 1; x [3] // නිර්වචනය නොකළ, සැබෑ අරාව සමඟ පමණි
Anona112

Ona ඇනෝනා 112 ඔබට Array.fromඋත්පාදක යන්ත්ර අරා සිද්ධීන් බවට පරිවර්තනය කිරීමට සහ ප්‍රතිදානය පරීක්ෂා කිරීමට භාවිතා කළ හැකිය .
පාවුලෝ මොරෙට්ටි

13

සම්මත ජාවාස්ක්‍රිප්ටයට පරාසයන් ජනනය කිරීම සඳහා සාදන ලද ශ්‍රිතයක් නොමැත. ජාවාස්ක්‍රිප්ට් රාමු කිහිපයක් එවැනි විශේෂාංග සඳහා සහය එක් කරයි, නැතහොත් අනෙක් අය පෙන්වා දී ඇති පරිදි ඔබට සැමවිටම ඔබේම දෑ පෙරළා ගත හැකිය.

ඔබ දෙවරක් පරීක්ෂා කිරීමට කැමති නම්, නියත සම්පත ECMA-262 ප්‍රමිතියයි .


2010 දී හොඳ පිළිතුරක් මට විශ්වාසයි, මෙය තවදුරටත් හොඳම ප්‍රවේශය ලෙස නොසැලකිය යුතුය. Prototype.js කිරීමට නැඹුරු වූවාක් මෙන් ඔබ ගොඩනගා ඇති වර්ග දීර් extend නොකළ යුතුය D
වුඩ්මන්

Ana ඩැනාවුඩ්මන් මෙය ගෙන ඒමට ස්තූතියි
මයික් ඩිනෙස්කු

26
හොඳයි, මෙය කිසිසේත් උදව් කළේ නැත.
පිටිකෝස්

1
IthPithikos මෙම ප්‍රශ්නය මුලින් ඇසූ දා සිට එය සංස්කරණය කර ඇති බව මට පෙනේ.
මයික් ඩිනෙස්කු

11

මෙය හොඳම ක්‍රමය නොවිය හැකිය. නමුත් ඔබ එක් කේත පේළියක සංඛ්‍යා පරාසයක් ලබා ගැනීමට බලාපොරොත්තු වන්නේ නම්. උදාහරණයක් ලෙස 10 - 50

Array(40).fill(undefined).map((n, i) => i + 10)

40 යනු (අවසානය - ආරම්භය) සහ 10 ආරම්භයයි. මෙය නැවත පැමිණිය යුතුය [10, 11, ..., 50]


10

සිත්ගන්නා සුළු අභියෝගයක් වනුයේ මෙය කිරීමට කෙටිම කාර්යය ලිවීමයි . ගලවා ගැනීමේ පුනරාවර්තනය!

function r(a,b){return a>b?[]:[a].concat(r(++a,b))}

විශාල පරාසයන්හි මන්දගාමී වීමට නැඹුරු වන නමුත් වාසනාවකට මෙන් ක්වොන්ටම් පරිගණක කෙළවරේ ය.

අමතර ප්‍රසාද දීමනාවක් නම් එය අපැහැදිලි ය. අපගේ කේතය පිරික්සීමේ ඇස්වලින් සඟවා ගැනීම කොතරම් වැදගත්දැයි අපි කවුරුත් දන්නා බැවිනි.

ශ්‍රිතය සැබවින්ම හා සම්පූර්ණයෙන්ම අපැහැදිලි කිරීමට, මෙය කරන්න:

function r(a,b){return (a<b?[a,b].concat(r(++a,--b)):a>b?[]:[a]).sort(function(a,b){return a-b})}

4
කෙටි! = සරල, නමුත් සරල වඩා හොඳය. මෙන්න කියවීමට පහසු අනුවාදය : const range = (a, b) => (a>=b) ? [] : [a, ...range(a+1, b)], ES6 සින්ටැක්ස් භාවිතා කරමින්
nafg

1
@nafg: const range = (a, b, Δ = 1) => (a > b) ? [] : [a, ...range(a + Δ, b, Δ)];. අදහස් දැක්වීම සඳහා සම්පූර්ණ පිළිතුරම ඉහළට ඔසවා තැබීම.
7vujy0f0hy

9

මම මේ වගේ දෙයක් කේත කරනවා:

function range(start, end) {
    return Array(end-start).join(0).split(0).map(function(val, id) {return id+start});
}  

range(-4,2);
// [-4,-3,-2,-1,0,1]

range(3,9);
// [3,4,5,6,7,8]

එය පයිතන් පරාසයට සමාන ලෙස ක්‍රියා කරයි:

>>> range(-4,2)
[-4, -3, -2, -1, 0, 1]

8

මෙම සිට කළ නොහැකි වුවත් , PHP , නමුත් අනුකරණය rangeසිට Python .

function range(start, end) {
    var total = [];

    if (!end) {
        end = start;
        start = 0;
    }

    for (var i = start; i < end; i += 1) {
        total.push(i);
    }

    return total;
}

console.log(range(10)); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
console.log(range(0, 10)); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(range(5, 10)); // [5, 6, 7, 8, 9] 

වේගවත්ම සඳහා +1. -36768 - 36768 අරාව සහිතව, මීටර් 3 ක් ද, දෙවන ස්ථානය එම්එස් 13 ක් ද, අයිඩීඊ රතු රේඛා ද ඇත.
mjwrazor

8

Array.from()ස්ථිතික ක්‍රමයට විශේෂ අවධානයක් යොමු කරමින් ES6 දැඩි ලෙස භාවිතා කරන තරමක් අවම ක්‍රියාත්මක කිරීමක් පහත පරිදි නිර්මාණය කළ හැකිය :

const getRange = (start, stop) => Array.from(
  new Array((stop - start) + 1),
  (_, i) => i + start
);

පැති සටහනක් ලෙස, මම සාරාංශයක් නිර්මාණය කර ඇති අතර එමඟින් මම getRange()විවිධාකාරයේ “වැඩිදියුණු කළ” ශ්‍රිතයක් කළෙමි . විශේෂයෙන්, මා අදහස් කළේ ඉහත හිස් අස්ථි ප්‍රභේදයේ අවධානයට ලක් නොවිය හැකි අද්දර සිද්ධීන් අල්ලා ගැනීමයි. ඊට අමතරව, මම අක්ෂරාංක පරාසයන් සඳහා සහය එක් කළෙමි. වෙනත් වචන වලින් කිවහොත්, 'C'සහ 'K'(එම අනුපිළිවෙල අනුව) වැනි යෙදවුම් දෙකකින් එය ඇමතීමෙන් 'සී' (ඇතුළත්) අකුරෙන් අනුක්‍රමික අක්ෂර සමූහයක් වන 'කේ' අක්ෂරය හරහා 'කේ' (සුවිශේෂී):getRange('C', 'K'); // => ["C", "D", "E", "F", "G", "H", "I", "J"]
ඉසෙන්රිච් ඕ

ඔබට newමූලික පදය අවශ්‍ය නැත
සොල්ඩෙප්ලාටා සකෙටෝස්

8

range(start,end,step): ES6 අනුකාරක සමඟ

ඔබ ඉල්ලන්නේ ඉහළ සහ පහළ සීමාවන් පමණි. මෙන්න අපි පියවරක් සමඟ එකක් නිර්මාණය කරමු.

ඔබට පහසුවෙන් range()උත්පාදක ශ්‍රිතයක් නිර්මාණය කළ හැකි අතර එය අනුකාරකයක් ලෙස ක්‍රියා කළ හැකිය. මෙයින් අදහස් කරන්නේ ඔබ සම්පූර්ණ අරාව පූර්ව උත්පාදනය කළ යුතු නැති බවයි.

function * range ( start, end, step = 1 ) {
  let state = start;
  while ( state < end ) {
    yield state;
    state += step;
  }
  return;
};

දැන් ඔබට අනුකාරකයෙන් අරාව පූර්ව උත්පාදනය කර ලැයිස්තුවක් ලබා දෙන යමක් නිර්මාණය කිරීමට අවශ්‍ය විය හැකිය. අරාව පිළිගන්නා කාර්යයන් සඳහා මෙය ප්‍රයෝජනවත් වේ. මේ සඳහා අපට භාවිතා කළ හැකියArray.from()

const generate_array = (start,end,step) =>
  Array.from( range(start,end,step) );

දැන් ඔබට පහසුවෙන් ස්ථිතික අරාවක් ජනනය කළ හැකිය,

const array1 = generate_array(1,10,2);
const array1 = generate_array(1,7);

නමුත් යම් දෙයක් නැවත ක්‍රියාකරවන්නෙකුට අවශ්‍ය වූ විට (හෝ ඔබට ඉරේටරයක් ​​භාවිතා කිරීමට විකල්පයක් ලබා දෙයි) ඔබට පහසුවෙන් එකක් නිර්මාණය කළ හැකිය.

for ( const i of range(1, Number.MAX_SAFE_INTEGER, 7) ) {
  console.log(i)
}

විශේෂ සටහන්


7

දී ඇති පරාසයක් සඳහා සංඛ්‍යාත්මක අරාවක් ජනනය කරන තාක් දුරට, මම මෙය භාවිතා කරමි:

function range(start, stop)
{
    var array = [];

    var length = stop - start; 

    for (var i = 0; i <= length; i++) { 
        array[i] = start;
        start++;
    }

    return array;
}

console.log(range(1, 7));  // [1,2,3,4,5,6,7]
console.log(range(5, 10)); // [5,6,7,8,9,10]
console.log(range(-2, 3)); // [-2,-1,0,1,2,3]

නිසැකවම, එය අකාරාදී අරා සඳහා ක්‍රියා නොකරනු ඇත.


කිරීම array = []කම්බියක් තුල ඔබට අවශ්ය දේ ඔබට නොහැකි විය හැක.
ඇලෙක්ස්

@alex, ස්තූතියි. ඔබ හරි, ලූපයේ සෑම පාස් එකකම “ආරම්භක” පරාමිතිය වැඩි කිරීමට මට අමතක විය. එය දැන් සවි කර ඇත.
jhaskell

එය තවමත් අපේක්ෂිත ප්‍රතිදානය නිපදවන්නේ නැත, මට 5-10 පරාසය අවශ්‍ය නම්, එය මට ලබා දෙනු ඇත [5, 6, 7, 8, 9, 10, 11, 12, 13, 14], මම බලාපොරොත්තු වන්නේ එම අරාවේ පළමු භාගය පමණි.
ඇලෙක්ස්

@alex, නැවතත් ස්තූතියි, ආදානය මත පදනම්ව දිග සීමාවක් මම නොසිතුවෙමි. යාවත්කාලීන කළ අනුවාදය බලන්න.
jhaskell

6

මෙය ප්‍රතිලෝමව ද ක්‍රියා කරයි.

const range = ( a , b ) => Array.from( new Array( b > a ? b - a : a - b ), ( x, i ) => b > a ? i + a : a - i );

range( -3, 2 ); // [ -3, -2, -1, 0, 1 ]
range( 1, -4 ); // [ 1, 0, -1, -2, -3 ]

5

භාවිතා එකමුතු ජනක යන්ත්ර , IE11 හැර සියලු බ්රව්සර් සහය :

var take = function (amount, generator) {
    var a = [];

    try {
        while (amount) {
            a.push(generator.next());
            amount -= 1;
        }
    } catch (e) {}

    return a;
};

var takeAll = function (gen) {
    var a = [],
        x;

    try {
        do {
            x = a.push(gen.next());
        } while (x);
    } catch (e) {}

    return a;
};

var range = (function (d) {
    var unlimited = (typeof d.to === "undefined");

    if (typeof d.from === "undefined") {
        d.from = 0;
    }

    if (typeof d.step === "undefined") {
        if (unlimited) {
            d.step = 1;
        }
    } else {
        if (typeof d.from !== "string") {
            if (d.from < d.to) {
                d.step = 1;
            } else {
                d.step = -1;
            }
        } else {
            if (d.from.charCodeAt(0) < d.to.charCodeAt(0)) {
                d.step = 1;
            } else {
                d.step = -1;
            }
        }
    }

    if (typeof d.from === "string") {
        for (let i = d.from.charCodeAt(0); (d.step > 0) ? (unlimited ? true : i <= d.to.charCodeAt(0)) : (i >= d.to.charCodeAt(0)); i += d.step) {
            yield String.fromCharCode(i);
        }
    } else {
        for (let i = d.from; (d.step > 0) ? (unlimited ? true : i <= d.to) : (i >= d.to); i += d.step) {
            yield i;
        }
    }
});

උදාහරණ

ගන්න

උදාහරණ 1.

take එය ලබා ගත හැකි තරම් ප්‍රමාණයක් ගනී

take(10, range( {from: 100, step: 5, to: 120} ) )

ප්‍රතිලාභ

[100, 105, 110, 115, 120]

උදාහරණ 2.

to අවශ්‍ය නැහැ

take(10, range( {from: 100, step: 5} ) )

ප්‍රතිලාභ

[100, 105, 110, 115, 120, 125, 130, 135, 140, 145]

සියලු ගැනීමට

උදාහරණ 3.

from අවශ්‍ය නැහැ

takeAll( range( {to: 5} ) )

ප්‍රතිලාභ

[0, 1, 2, 3, 4, 5]

උදාහරණ 4.

takeAll( range( {to: 500, step: 100} ) )

ප්‍රතිලාභ

[0, 100, 200, 300, 400, 500]

උදාහරණ 5.

takeAll( range( {from: 'z', to: 'a'} ) )

ප්‍රතිලාභ

["z", "y", "x", "w", "v", "u", "t", "s", "r", "q", "p", "o", "n", "m", "l", "k", "j", "i", "h", "g", "f", "e", "d", "c", "b", "a"]


මගේ යෝජනා සමඟ සංස්කරණය කරන ලදි :)
Xotic750

ප්රවේශය සඳහා +1. @ ඇලෙක්ස්ගේ කරුණට අනුව, forවගන්තියේ ත්‍රිමාණ මෙහෙයුම් (විශේෂයෙන් කැදැලි නොකිරීම) මෙහි කියවීමේ හැකියාව වැඩි කරයි.
ජස්ටින් ජොන්සන්

5

... වැඩි පරාසයක්, උත්පාදක ශ්‍රිතයක් භාවිතා කිරීම.

function range(s, e, str){
  // create generator that handles numbers & strings.
  function *gen(s, e, str){
    while(s <= e){
      yield (!str) ? s : str[s]
      s++
    }
  }
  if (typeof s === 'string' && !str)
    str = 'abcdefghijklmnopqrstuvwxyz'
  const from = (!str) ? s : str.indexOf(s)
  const to = (!str) ? e : str.indexOf(e)
  // use the generator and return.
  return [...gen(from, to, str)]
}

// usage ...
console.log(range('l', 'w'))
//=> [ 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w' ]

console.log(range(7, 12))
//=> [ 7, 8, 9, 10, 11, 12 ]

// first 'o' to first 't' of passed in string.
console.log(range('o', 't', "ssshhhooooouuut!!!!"))
// => [ 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 't' ]

// only lowercase args allowed here, but ...
console.log(range('m', 'v').map(v=>v.toUpperCase()))
//=> [ 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V' ]

// => and decreasing range ...
console.log(range('m', 'v').map(v=>v.toUpperCase()).reverse())

// => ... and with a step
console.log(range('m', 'v')
          .map(v=>v.toUpperCase())
          .reverse()
          .reduce((acc, c, i) => (i % 2) ? acc.concat(c) : acc, []))

// ... etc, etc.

මෙය ප්‍රයෝජනවත් යැයි සිතමි.



5

දේවල් කෙටි හා සරල ලෙස තබා ගැනීමට ඔබට පහත දැක්වෙන එක්-ලයිනර් භාවිතා කළ හැකිය

var start = 4;
var end = 20;
console.log(Array(end - start + 1).fill(start).map((x, y) => x + y));



4

d3 හි පරාසයේ ශ්‍රිතයක් ද ඇත. Https://github.com/mbostock/d3/wiki/Arrays#d3_range බලන්න :

d3.range ([ආරම්භ කරන්න,] නවත්වන්න [, පියවර])

පයිතන් සාදන ලද පරාසයට සමාන අංක ගණිතමය ප්‍රගතියක් සහිත අරාවක් ජනනය කරයි. මෙම ක්‍රමය බොහෝ විට භාවිතා කරනුයේ සංඛ්‍යාත්මක හෝ පූර්ණ සංඛ්‍යා අගයන්, එනම් දර්ශක අරාවකට අනුක්‍රමණය කිරීම සඳහා ය. පයිතන් අනුවාදය මෙන් නොව, තර්ක පූර්ණ සංඛ්‍යා විය යුතු නැත, නමුත් පාවෙන ලක්ෂ්‍ය නිරවද්‍යතාවය නිසා ප්‍රති results ල වඩාත් පුරෝකථනය කළ හැකිය. පියවර මඟ හැරී ඇත්නම්, එය පෙරනිමිය 1 දක්වා වේ.

උදාහරණයක්:

d3.range(10)
// returns [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

මම දැනගෙන හිටියේ නැහැ D3 පවතින බව. ඔවුන්ගේ පරාස ක්‍රමය භාවිතා කිරීමට නොයන නමුත් මෙම පැකේජය භාවිතා කරනු ඇත.
mjwrazor

ඔයාට බොහෝම ස්තූතියි. මම D3 භාවිතා කරන අතර දේශීය JS ක්‍රමයක් සොයමින් සිටියෙමි, මම දැනටමත් D3 එය ලබා දෙන බව නොදැන.
cezar

4

පරාසය ([ආරම්භක,] නැවතුම් [, පියවර]) අත්සන භාවිතා කරමින් සම්පූර්ණ ES6 ක්‍රියාත්මක කිරීම:

function range(start, stop, step=1){
  if(!stop){stop=start;start=0;}
  return Array.from(new Array(int((stop-start)/step)), (x,i) => start+ i*step)
}

ඔබට ස්වයංක්‍රීය negative ණ පියවරක් අවශ්‍ය නම් එකතු කරන්න

if(stop<start)step=-Math.abs(step)

හෝ වඩාත් අවම වශයෙන්:

range=(b, e, step=1)=>{
  if(!e){e=b;b=0}
  return Array.from(new Array(int((e-b)/step)), (_,i) => b<e? b+i*step : b-i*step)
}

ඔබට විශාල පරාසයන් තිබේ නම් පාවුලෝ මොරෙට්ටිගේ උත්පාදක ප්‍රවේශය දෙස බලන්න


වෙනුවට !stopසමග typeof stop === 'undefined', පසුව වෙනුවට intසමග Math.floor, සහ චෙක් එකතු if (start > stop && step > 0)(නැත්නම්, range(-3, -10)යම් දෙයක් සිහිකල්පනාව (පියවර ලකුණ බංකොලොත් කරවීමෙන් හෝ නැවත එක්කෝ කරන්නේ වෙනුවට ව්යතිරේකයක් අවුලට [])). නැතිනම් හොඳයි!
අහමඩ් ෆාසි
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.