programing

Python range()와 유사한 JavaScript 함수

closeapi 2023. 7. 20. 21:57
반응형

Python range()와 유사한 JavaScript 함수

의 파이썬과 비슷한 이 요?range()?

매번 다음과 같은 대사를 쓰는 것보다 더 좋은 방법이 있어야 한다고 생각합니다.

array = new Array();
for (i = 0; i < specified_len; i++) {
    array[i] = i;
}

ES6에서 매우 단순한 범위의 경우:

let range = n => Array.from(Array(n).keys())

bigOmega의 설명에 따르면, 이것은 스프레드 구문을 사용하여 단축할 수 있습니다.

let range = n => [...Array(n).keys()]

아니요, 없어요, 하지만 당신은 만들 수 있어요.

range()

Python에서 작동하는 방식을 에뮬레이트하기 위해 다음과 같은 기능을 만들 것입니다.

function range(start, stop, step) {
    if (typeof stop == 'undefined') {
        // one param defined
        stop = start;
        start = 0;
    }

    if (typeof step == 'undefined') {
        step = 1;
    }

    if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) {
        return [];
    }

    var result = [];
    for (var i = start; step > 0 ? i < stop : i > stop; i += step) {
        result.push(i);
    }

    return result;
};

자세한 내용은 이 jsfidle을 참조하십시오.

range() 및 PythonJavaScript 및Python 서

다음과 같은 방식으로 작동합니다.

  • range(4)아온다를 합니다.[0, 1, 2, 3],
  • range(3,6)아온다를 합니다.[3, 4, 5],
  • range(0,10,2)아온다를 합니다.[0, 2, 4, 6, 8],
  • range(10,0,-1)아온다를 합니다.[10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
  • range(8,2,-2)아온다를 합니다.[8, 6, 4],
  • range(8,2)아온다를 합니다.[],
  • range(8,2,2)아온다를 합니다.[],
  • range(1,5,-1)아온다를 합니다.[],
  • range(1,5,-2)아온다를 합니다.[],

그리고 Python 대응물은 정확히 동일한 방식으로 작동합니다(최소한 언급된 경우).

>>> range(4)
[0, 1, 2, 3]
>>> range(3,6)
[3, 4, 5]
>>> range(0,10,2)
[0, 2, 4, 6, 8]
>>> range(10,0,-1)
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
>>> range(8,2,-2)
[8, 6, 4]
>>> range(8,2)
[]
>>> range(8,2,2)
[]
>>> range(1,5,-1)
[]
>>> range(1,5,-2)
[]

따라서 파이썬과 유사하게 작동하는 기능이 필요하다면,range()위에 언급된 솔루션을 사용할 수 있습니다.

@Tadek@gorg의 두 가지 대답을 종합하여, 저는 다음과 같은 것을 생각해냈습니다.

function* range(start, stop, step = 1) {
    if (stop == null) {
        // one param defined
        stop = start;
        start = 0;
    }

    for (let i = start; step > 0 ? i < stop : i > stop; i += step) {
        yield i;
    }
}

for 루프에서 사용하려면 ES6/JS1.7 for-of 루프가 필요합니다.

for (let i of range(5)) {
    console.log(i);
}
// Outputs => 0 1 2 3 4

for (let i of range(0, 10, 2)) {
    console.log(i);
}
// Outputs => 0 2 4 6 8

for (let i of range(10, 0, -2)) {
    console.log(i);
}
// Outputs => 10 8 6 4 2

2018년: 이 답변은 계속해서 투표를 얻고 있습니다. 그래서 여기 업데이트가 있습니다. ES6 와 ES6 표준화 발전기는yield여러 플랫폼에서 보편적으로 지원되는 키워드입니다.의 예range()용사를 yield여기서 찾을 수 있습니다.


이미 말한 것 외에도 Javascript 1.7+는 게으르고 메모리 효율적인 버전을 만드는 데 사용할 수 있는 반복기생성기를 지원합니다.range와비한과 xrange Python2에서:

function range(low, high) {  
    return {
        __iterator__: function() {
            return {  
                next: function() {
                    if (low > high)
                        throw StopIteration;  
                    return low++;
                }
            }
        }
    }
}

for (var i in range(3, 5))  
  console.log(i); // 3,4,5

rangePython 2의 함수는 언더스코어.jslodash 유틸리티 라이브러리(다른 많은 유용한 도구)에 의해 제공됩니다.밑줄 문서에서 복사한 예:

_.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);
=> []

에 .Number 제작

  Number.prototype[Symbol.iterator] = function* () { 
     for (var i = 0; i <= this; i++) {
       yield i
     } 
  }

[...5] // will result in [0,1,2,3,4,5]

비동기 자바스크립트를 다시 생각하는 Kyle Simpson의 과정에서 발췌.

다음은 범위의 시작 위치와 종료 위치를 모두 지정해야 할 경우를 대비하여 답변 중 하나를 위한 작은 확장입니다.

let range = (start, end) => Array.from(Array(end + 1).keys()).slice(start);

여기 있어요.

이렇게 하면 각 인덱스의 값이 인덱스 번호로 기록(또는 덮어씁니다)됩니다.

Array.prototype.writeIndices = function( n ) {
    for( var i = 0; i < (n || this.length); ++i ) this[i] = i;
    return this;
};

숫자를 입력하지 않으면 배열의 현재 길이가 사용됩니다.

다음과 같이 사용합니다.

var array = [].writeIndices(10);  // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

pythonic 파이썬을 모방합니다.rangeJS의 잘 할 수 행동(JS 할최행동선의있는수여를용하전기사발)yield), , , 를 range(stop)그리고.range(start, stop, step)사용 사례게다가.pythonicrange은 함수반니다합을 합니다.Iterator Python을 합니다.map그리고.filter그래서 다음과 같은 멋진 한 줄기를 할 수 있습니다.

import {range} from 'pythonic';
// ...
const results = range(5).map(wouldBeInvokedFiveTimes);
// `results` is now an array containing elements from
// 5 calls to wouldBeInvokedFiveTimes

를 사용하여 npm:

npm install --save pythonic

공개 저는 파이썬의 저자이자 유지보수자입니다.

ES6 기본 매개 변수로 더욱 세분화되었습니다.

let range = function*(start = 0, stop, step = 1) {
  let cur = (stop === undefined) ? 0 : start;
  let max = (stop === undefined) ? start : stop;
  for (let i = cur; step < 0 ? i > max : i < max; i += step)
    yield i
}

다음은 Python의 range() 함수를 JavaScript에 자연스럽게 적용한 것입니다.

// Generate range from start (inclusive) to stop (exclusive):
function* range(start, stop, step = 1) {
   if (stop === undefined) [start, stop] = [0, start];
   if (step > 0) while (start < stop) yield start, start += step;
   else if (step < 0) while (start > stop) yield start, start += step;
   else throw new RangeError('range() step argument invalid');
} 

// Examples:
console.log([...range(3)]);       // [0, 1, 2]
console.log([...range(0, 3)]);    // [0, 1, 2]
console.log([...range(0, 3, -1)]);// []
console.log([...range(0, 0)]);    // []
console.log([...range(-3)]);      // []
console.log([...range(-3, 0)]);   // [-3, -2, -1]

비교할 수 있는 모든 인수를 지원합니다.0그리고.stop증가할 수 있습니다.step다음을 초과하지 않는 숫자로 사용할 경우 Python 버전과 동일하게 동작합니다.Number.MAX_SAFE_INTEGER.

다음 코너 사례에 유의하십시오.

[...range(0, 0, 0)];        // RangeError: range() step argument invalid
[...range(Number.MAX_SAFE_INTEGER + 1, Number.MAX_SAFE_INTEGER + 2)];  // []
[...range(Number.MAX_SAFE_INTEGER + 2, Number.MAX_SAFE_INTEGER + 3)];  // Infinite loop
[...range(0.7, 0.8, 0.1)];  // [0.7, 0.7999999999999999]
[...range('1', '11')];      // ['1']
[...range('2', '22')];      // Infinite loop

@Tadek의 답과 대조적으로, @Volv와 @janka102의 답은 돌아오는 것입니다.[],undefined 때 무한 루프에 들어갑니다.step으로 됩니다.0또는NaN이 생성기 함수는 Python의 동작과 유사한 예외를 발생시킵니다.

현대적인 솔루션을 원하는 모든 사용자에게 적합[...Array(n).keys()]

크기배열얻위해기을▁of▁an위.x 도서관을 가 있습니다.

var range = n => Array(n + 1).join(1).split('').map((x, i) => i)

로 작동하는.

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

MDN은 이 접근 방식을 권장합니다. 시퀀스 생성기(범위)

// Sequence generator function (commonly referred to as "range", e.g. Clojure, PHP etc)
const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));

// Generate numbers range 0..4
console.log("range(0, 4, 1):", range(0, 4, 1));
// [0, 1, 2, 3, 4] 

// Generate numbers range 1..10 with step of 2 
console.log("\nrange(1, 10, 2):", range(1, 10, 2));
// [1, 3, 5, 7, 9]

// Generate the alphabet using Array.from making use of it being ordered as a sequence
console.log("\nrange('A'.charCodeAt(0), 'Z'.charCodeAt(0), 1).map(x => String.fromCharCode(x))", range('A'.charCodeAt(0), 'Z'.charCodeAt(0), 1).map(x => String.fromCharCode(x)));
// ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]

실제로 Python range()에서는 반복 가능한 개체를 반환하고 반복기가 배열(또는 Python의 목록)보다 메모리 효율성이 높다는 것을 알고 있습니다.따라서 JavaScript에서 동일한 개념을 정확한 기능으로 구현하려면 반복기 개체를 사용할 수 있습니다.

class range {

constructor(start, stop, step = 1) {
    //check for invalid input
    if (stop !== undefined && typeof stop !== 'number'
        || typeof start !== 'number'
        || typeof step !== 'number') {
        throw Error('invalid input for range function');
    }

    //check if second argument is provided
    if (stop === undefined) {
        stop = start;
        start = 0;
    }

    //initialize the object properties
    this.start = start;
    this.stop = stop;
    this.step = step;
}

//create the iterator object with Symbol.iterator
[Symbol.iterator]() {
    return {
        current: this.start,
        last: this.stop,
        step: this.step,
        //implement the next() method of the iterator
        next() {
            if (this.step === 0) {
                return { done: true };
            } else if (this.step > 0 ? this.current < this.last : this.current > this.last) {
                let value = this.current;
                this.current += this.step;
                return { done: false, value };
            } else {
                return { done: true };
            }
        }
    };
};
}

예를 들어 다음과 같습니다.

for (const num of new range(1, 10, 2)) {
console.log(num);
}

또한 어레이를 쉽게 만들 수 있습니다.

let arr = [...new range(10, -5, -1)];

또는:

let arr = Array.from(new range(10));

자바스크립트에 파이썬의 범위()와 유사한 기능이 있습니까?

여기에 있는 모든 솔루션은 Python 2의 범위를 참조하고 있습니다(아마 당신이 제공한 코드 예제 때문일 것입니다).그러나 Python 3에서는 range() 메서드가 반복기를 반환합니다.JavaScript에는 반복기도 있으며 전체 어레이를 생성하여 메모리에 저장하는 것보다 공간 효율성이 높습니다.

의 Python 3을 더 할 수 .range(n)는 기은능입니다.Array(n).keys().

예:

for (let i of Array(n).keys()) {
  console.log(i) // 0, 1, 2, 3, ..., n
}

예를 하나 더 들어보겠습니다(다른 답변에서 이미 설명했습니다).반복기를 배열로 변환(ES6):

let ary = [...Array(n).keys()];
// ary = [0, 1, 2, 3, ..., n]

밑줄 라이브러리를 사용할 수 있습니다.어레이 작업에 유용한 수십 가지 기능을 포함하고 있습니다.

여전히 다음과 같은 기능이 내장되어 있지 않습니다.range()그러나 최신 버전인 ES2015를 사용하면 직접 구현을 구축할 수 있습니다.여기 한정판이 있습니다.단계 매개 변수를 고려하지 않기 때문에 제한됩니다.최소, 최대.

const range = (min = null, max = null) =>
  Array.from({length:max ? max - min : min}, (v,k) => max ? k + min : k)

은 이작은다수니다행됩통해음을에 됩니다.Array.from모든 객체에서 어레이를 구축할 수 있는 방법.length소유물.그래서 그냥 간단한 물건을 전달하는 것.length하여 ArrayIterator를 생성합니다.length개체 수.

이것이 제가 선호하는 방법입니다.Python처럼 입력을 하나 또는 두 개 지정할 수 있습니다.

function range(start, end) {
  return Array.from(Array(end||start).keys()).slice(!!end*start)
}

자바스크립트에 파이썬의 범위()와 유사한 기능이 있습니까?

전에 대답했듯이, 없습니다.하지만 당신은 당신만의 것을 만들 수 있습니다.저는 이것이 ES6를 위한 흥미로운 접근법이라고 생각합니다.Python 2.7과 매우 유사하게 작동합니다.range()하지만 훨씬 더 역동적입니다.

function range(start, stop, step = 1) 
{
    // This will make the function behave as range(stop)
    if(arguments.length === 1)
    {
        return [...Array(arguments[0]).keys()]
    }

    // Adjusts step to go towards the stop value
    if((start > stop && !(step < 0)) ||
       (start < stop && !(step > 0)))
    {
        step *= -1
    }

    let returnArray = []
    // Checks if i is in the interval between start and stop no matter if stop
    // is lower than start or vice-versa
    for(let i = start; (i-start)*(i-stop) <= 0; i += step)
    {
        returnArray.push(i)
    }
    return returnArray
}

이 함수는 세 가지 방식으로 동작할 수 있습니다(파이썬의 범위()처럼).

  1. range(stop)
  2. range(start, stop)
  3. range(start, stop, step)

다음은 예입니다.

console.log(range(5))
console.log(range(-2, 2))
console.log(range(2, -2))
console.log(range(10, 20, 2))

다음과 같은 출력을 제공합니다.

[ 0, 1, 2, 3, 4 ]
[ -2, -1, 0, 1, 2 ]
[ 2, 1, 0, -1, -2 ]
[ 10, 12, 14, 16, 18, 20 ]

에 " 를반복대신는하여사용하이"를합니다.in연산자는 연자파럼산처사합니, 당은야해다용신썬이를 사용해야 .of 그므로러는i합니다.

for(let i of range(5))
{
    // do something with i...
}

NodeJs의 옵션은 버퍼를 사용하는 것입니다.

[...Buffer.alloc(5).keys()]
// [ 0, 1, 2, 3, 4 ]

좋은 점은 버퍼에서 직접 반복할 수 있다는 것입니다.

Buffer.alloc(5).forEach((_, index) => console.log(index))
// 0
// 1
// 2
// 3
// 4

초기화되지 않은 어레이에서는 이 작업을 수행할 수 없습니다.

Array(5).forEach((_, index) => console.log(index))
// undefined

하지만, 제정신으로 이런 목적으로 버퍼를 사용하는 사람;)

function range(start, stop) {
    if (typeof stop == 'undefined') {
        stop = start;
        start = 0;
    }
   
    result = [...Array(stop).keys()].slice(start, stop);
    return result;
}

또 다른 여기또니다습있이 있습니다.es6의 실시

// range :: (from, to, step?) -> [Number]
const range = (from, to, step = 1) => {
  //swap values if necesery
  [from, to] = from > to ? [to, from] : [from, to]
  //create range array
  return [...Array(Math.round((to - from) / step))]
    .map((_, index) => {
      const negative = from < 0 ? Math.abs(from) : 0
      return index < negative ? 
        from + index * step  :
        (index - negative + 1) * step
    })
}  

range(-20, 0, 5)
  .forEach(val => console.log(val))

for(const val of range(5, 1)){
   console.log(`value ${val}`)
}

아니요, 없어요, 하지만 당신은 만들 수 있어요.

저는 범위의 Python3 행동을 선호합니다.아래에서 자바스크립트의 파이썬 범위 구현()을 확인할 수 있습니다.

function* range(start=0, end=undefined, step=1) {    
    if(arguments.length === 1) {end = start, start = 0}    
    
    [...arguments].forEach(arg => {    
        if( typeof arg !== 'number') {throw new TypeError("Invalid argument")}                               
    })    
    if(arguments.length === 0) {throw new TypeError("More arguments neede")}    
        
    if(start >= end) return                                                                                                                                     
    yield start    
    yield* range(start + step, end, step)    
}    
         
// Use Cases
console.log([...range(5)])

console.log([...range(2, 5)])

console.log([...range(2, 5, 2)])
console.log([...range(2,3)])
// You can, of course, iterate through the range instance.

단일 단계에서 간단한 범위가 필요하다고 가정합니다.

let range = (start, end)=> {
    if(start === end) return [start];
    return [start, ...range(start + 1, end)];
}

또 다른

let range = (start, end, step)=> {
    if(start === end) return [start];
    return [start, ...range(start + step, end)];
}

자세한 내용은 여기를 참조하십시오.

제가 하는 방법은 이렇습니다.

let n = 5 
[...Array(n).keys()].map(x=>{console.log(x)})

산출량

0
1
2
3
4
/**
 * range generator
 *
 * @param {Integer} start - Optional. An integer specifying at which position to start. Default is 0
 * @param {Integer} stop  - Required. An integer specifying at which position to stop. Excluded.
 * @param {Integer} step  - Optional. An integer specifying the incrementation. Default is 1
 */

function* range (start, stop, step = 1) {

  if (arguments.length === 1) { [start, stop] = [0, start]; }

  if (![start, stop, step].every(Number.isInteger)) { throw new TypeError('range needs integer arguments'); }

  if ((start - stop) * step >= 0) { return []; }

  let check = start > stop ? (a, b) => a > b : (a, b) => a < b;
  while (check(start, stop)) { yield start, start += step; }
}

console.log([...range(4)]);
console.log([...range(2, 4)]);
console.log([...range(1, 4, 2)]);
console.log([...range(-4, -1, 1)]);
console.log([...range(10, 4, -2)]);
console.log([...range(-1, -4, -1)]);

오류 검사가 없는 유형 스크립트의 간단한 접근 방식입니다.스텝 속도를 포함한 상승 및 하강.

const range = (start: number, end: number | null = null, step: number = 1): number[] =>
  [...Array(end === null ? start : Math.abs(end - start)).keys()]
    .filter((n: number): boolean => n % step === 0)
    .map((n: number): number => (end === null ? n : end < start ? Math.max(start, end) - n : n + start));

Javascript ES6에서도 동일

const range = (start, end = null, step = 1) =>
  [...Array(end === null ? start : Math.abs(end - start)).keys()]
    .filter((n) => n % step === 0)
    .map((n) => (end === null ? n : end < start ? Math.max(start, end) - n : n + start));
const range = function*(start, stop, inclusive=false) {
    let dx = Math.sign(stop - start);
    if (inclusive) stop += dx;
    for (let x = start; x !== stop; x += dx) yield x;
}

const arange = (start, stop, inclusive) => [...range(start, stop, inclusive)];

간결하고, 포괄적인 es6 재미.코데펜 데모

var rng=(s,e=null,d=1)=>{
  if(e==null)var[s,e]=[0,s]//missing e? s is e
  if(s>e)d=d<0?d:-d//s,e backwards? might flip sign
  return[...Array(((e-s)/d+1) << 0).keys()].map(x=>d*x+s)
}

rng(3) -> [0,1,2,3]
rng(0,2) -> [0,1,2]
rng(4,6) -> [4,5,6]
rng(3,9,3) -> [3,6,9]
rng(10,27,5) -> [10,15,20,25]
rng(7,null,2) -> [0,2,4,6]
rng(3,-2) -> [3,2,1,0,-1,-2]
rng(3,-2,-2) -> [3,1,-1]
rng(3,-2,2) -> [3,1,-1]
rng(42,42) -> [42]

((으)를 +1어레이()에서 유용/호환 가능합니다.)

언급URL : https://stackoverflow.com/questions/8273047/javascript-function-similar-to-python-range

반응형