在 Javascript/jQuery 中创建两个数字之间的所有整数的数组(包括两个数字)

发布于 2024-12-14 16:18:59 字数 527 浏览 1 评论 0原文

假设我有以下复选框:

<input type="checkbox" value="1-25" />

要获取定义我正在查找的范围边界的两个数字,我使用以下 jQuery:

var value = $(this).val();
var lowEnd = Number(value.split('-')[0]);
var highEnd = Number(value.split('-')[1]);

然后如何创建一个包含 lowEnd 之间所有整数的数组和 highEnd,包括 lowEndhighEnd 本身?对于这个具体示例,显然,结果数组将是:

[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]

Say I have the following checkbox:

<input type="checkbox" value="1-25" />

To get the two numbers that define the boundaries of range I'm looking for, I use the following jQuery:

var value = $(this).val();
var lowEnd = Number(value.split('-')[0]);
var highEnd = Number(value.split('-')[1]);

How do I then create an array that contains all integers between lowEnd and highEnd, including lowEnd and highEnd themselves? For this specific example, obviously, the resulting array would be:

[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]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(25

墨小沫ゞ 2024-12-21 16:19:39

在测试和调整上述所有纯 js 解决方案之后,我为您提供以下解决方案,基于所提供的最快算法,并且与 python 系列兼容。

js 版本更好,因为它支持小数。

function range(start, end, step=1) {
    if (typeof end === 'undefined') {
        end = start, start = 0;
    }
    let len = Math.round((end - start) / step);
    let arr = [];
    while ( len-- ) {
        arr[len] = start + (len * step);
    }
    return arr;
}
console.log(range(9, 18, 0.83));
/* [
  9,
  9.83,
  10.66,
  11.49,
  12.32,
  13.149999999999999,
  13.98,
  14.809999999999999,
  15.64,
  16.47,
  17.299999999999997
] */
console.log(range(9, 18, 2)); // [9, 11, 13, 15, 17]
console.log(range(9, 18)); // [9, 10, 11, 12, 13, 14, 15, 16, 17]
console.log(range(9)); // [0, 1, 2, 3, 4, 5, 6, 7, 8]

请参阅 python 代码,仅适用于整数:

print(list(range(9, 18, 2))); # [9, 11, 13, 15, 17]
print(list(range(9, 18))); # [9, 10, 11, 12, 13, 14, 15, 16, 17]
print(list(range(9))); # [0, 1, 2, 3, 4, 5, 6, 7, 8]

After testing and adjusting all the pure js solutions above, I offer you the following solution, based on the fastest algo offered, and compatible with the python range.

The js version is even better, since it supports decimals.

function range(start, end, step=1) {
    if (typeof end === 'undefined') {
        end = start, start = 0;
    }
    let len = Math.round((end - start) / step);
    let arr = [];
    while ( len-- ) {
        arr[len] = start + (len * step);
    }
    return arr;
}
console.log(range(9, 18, 0.83));
/* [
  9,
  9.83,
  10.66,
  11.49,
  12.32,
  13.149999999999999,
  13.98,
  14.809999999999999,
  15.64,
  16.47,
  17.299999999999997
] */
console.log(range(9, 18, 2)); // [9, 11, 13, 15, 17]
console.log(range(9, 18)); // [9, 10, 11, 12, 13, 14, 15, 16, 17]
console.log(range(9)); // [0, 1, 2, 3, 4, 5, 6, 7, 8]

see the python code, for integers only:

print(list(range(9, 18, 2))); # [9, 11, 13, 15, 17]
print(list(range(9, 18))); # [9, 10, 11, 12, 13, 14, 15, 16, 17]
print(list(range(9))); # [0, 1, 2, 3, 4, 5, 6, 7, 8]
一念一轮回 2024-12-21 16:19:37
        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;
        }

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

荒人说梦 2024-12-21 16:19:37
_Array = (length) => Object.keys(Array.from({length}))

//_Array = [0, 1, 2, 3, 4]
_Array = (length) => Object.keys(Array.from({length}))

//_Array = [0, 1, 2, 3, 4]
南…巷孤猫 2024-12-21 16:19:35

打字稿版本:

function getAllNumbersBetween(start: number, end: number) {
  var numbers: number[] = [];

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

  return numbers;
}

Typescript version:

function getAllNumbersBetween(start: number, end: number) {
  var numbers: number[] = [];

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

  return numbers;
}
淡紫姑娘! 2024-12-21 16:19:35

解决下划线

data = [];
_.times( highEnd, function( n ){ data.push( lowEnd ++ ) } );

Solving in underscore

data = [];
_.times( highEnd, function( n ){ data.push( lowEnd ++ ) } );
叫嚣ゝ 2024-12-21 16:19:33
const range = (start: number, end: number) => {
  for (var i = start, list = []; i <= end; list.push(i), i++);
  return list;
};

const range = (start: number, end: number) => {
  for (var i = start, list = []; i <= end; list.push(i), i++);
  return list;
};

蝶舞 2024-12-21 16:19:33

希望下面的方法对某人有所帮助。
这里count变量可以用来表示数组长度。

const generateRandomArryOfNumbers = (min = 1, max = 100, count = 31) => {
  return Array.from(new Array(count), () =>
    Math.floor(Math.random() * (max - min + 1) + min)
  );
};

Hope the below method will help someone.
Here count variable can be used to mention the array length.

const generateRandomArryOfNumbers = (min = 1, max = 100, count = 31) => {
  return Array.from(new Array(count), () =>
    Math.floor(Math.random() * (max - min + 1) + min)
  );
};
物价感观 2024-12-21 16:19:32

处理此问题的一种优雅且通用的方法是创建一个生成器:

/**
 * Generates a range of numbers from start to end inclusively.
 */
function* range(start: number, end: number) {
  for (let value = start; value <= end; value += 1) {
    yield value;
  }
}

然后您可以在其上使用扩展运算符:

[...range(30, 275)].map(value => `${value} cm`)

function* 语法表示一个生成器,它可以暂停执行并从停止的位置恢复。它允许它随着时间的推移生成一系列值,而不是一次计算所有值并返回它们。

An elegant and versatile way to handle this is to create a generator:

/**
 * Generates a range of numbers from start to end inclusively.
 */
function* range(start: number, end: number) {
  for (let value = start; value <= end; value += 1) {
    yield value;
  }
}

Then you can use the spread operator on it:

[...range(30, 275)].map(value => `${value} cm`)

The function* syntax denotes a generator which can pause execution and resume from where it left off. It allows it to produce a sequence of values over time instead of computing them all at once and returning them.

绿光 2024-12-21 16:19:29

你可以在 ES6 中一行完成

const start = 5; // starting number
const end = 10; // ending number

const arr = Array.from({ length: end - start + 1 }, (_, i) => start + i);

console.log(arr); // [5, 6, 7, 8, 9, 10]

You can do that in one line in ES6

const start = 5; // starting number
const end = 10; // ending number

const arr = Array.from({ length: end - start + 1 }, (_, i) => start + i);

console.log(arr); // [5, 6, 7, 8, 9, 10]
那片花海 2024-12-21 16:19:28
const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));

来源:https://developer.mozilla。 org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));

source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

傲影 2024-12-21 16:19:26

这里有 3 个函数应该涵盖我能想到的所有内容(包括修复其他一些答案中的问题):rangeInt()range()Between( )。在所有情况下都考虑升序和降序。

示例

rangeInt()

包括端点并仅处理整数

rangeInt(1, 4)  // [1, 2, 3, 4] Ascending order
rangeInt(5, 2)  // [5, 4, 3, 2] Descending order
rangeInt(4, 4)  // [4]          Singleton set (i.e. not [4, 4])
rangeInt(-1, 1) // [-1, 0, 1]   Mixing positive and negative

range()

rangeInt() 相同,但

  1. 不限于整数
  2. 允许指定数字第三个参数中的点
range(0, 10, 2)  // [0, 3.333, 6.666, 10] Gets endpoints and 2 points between
range(0, 1.5, 1) // [0, 0.75, 1.5]        Accepts fractions

Between()

range() 相同,但

  1. 排除端点
  2. 没有单例集(将返回空数组)
between(0, 10, 2) // [3.333, 6.666]
between(-1, -1.5) // [-1.25]
between(4, 4, 99) // []

/**
 * Gets a set of integers that are evenly distributed along a closed interval
 * @param {int} begin - Beginning endpoint (inclusive)
 * @param {int} end   - Ending endpoint (inclusive)
 * @return {Array} Range of integers
 */
function rangeInt( begin, end )  {
    if ( !Number.isInteger(begin) || !Number.isInteger(end) ) {
        throw new Error('All arguments must be integers')
    }
    return range(begin, end, Math.abs(end - begin) - 1)
}

/**
 * Gets a set of numbers that are evenly distributed along a closed interval
 * @param {Number} begin  - Beginning endpoint (inclusive)
 * @param {Number} end    - Ending endpoint (inclusive)
 * @param {int}    points - How many numbers to retrieve from the open interval
 * @return {Array} Range of numbers
 */
function range( begin, end, points ) {
    if ( begin !== end ) {
        return [ begin, ...between(begin, end, points), end ]
    }
    else if ( Number.isFinite(begin) ) {
        return [ begin ] // singleton set
    }
    else throw new Error('Endpoints must be finite')
}

/**
 * Gets a subset of numbers that are evenly distributed along an open interval
 * @param {Number} begin  - Beginning endpoint (exclusive)
 * @param {Number} end    - Ending endpoint (exclusive)
 * @param {int}    points - How many numbers to retrieve from the interval
 * @return {Array} Retrieved numbers
 */
function between( begin, end, points = 1 ) {
    if ( !Number.isFinite(begin) || !Number.isFinite(end) || !Number.isFinite(points) ) {
        throw new Error('All arguments must be finite')
    }
    const set = []
    // Skip if an open interval does not exist
    if ( begin !== end ) {
        const step = (end - begin) / (points + 1)
        for ( let i = 0; i < points; i++ ) {
            set[i] = begin + (i + 1) * step
        }
    }
    return set
}

Here's 3 functions that should cover everything I could think of (including fixes for problems in some other answers): rangeInt(), range(), and between(). Both ascending and descending orders are accounted for in all cases.

Examples

rangeInt()

Includes endpoints and only deals with integers

rangeInt(1, 4)  // [1, 2, 3, 4] Ascending order
rangeInt(5, 2)  // [5, 4, 3, 2] Descending order
rangeInt(4, 4)  // [4]          Singleton set (i.e. not [4, 4])
rangeInt(-1, 1) // [-1, 0, 1]   Mixing positive and negative

range()

Same as rangeInt() except

  1. Not limited to integers
  2. Allows for a specified number of points in a third parameter
range(0, 10, 2)  // [0, 3.333, 6.666, 10] Gets endpoints and 2 points between
range(0, 1.5, 1) // [0, 0.75, 1.5]        Accepts fractions

between()

Same as range() except

  1. Endpoints are excluded
  2. There are no singleton sets (an empty array will be returned instead)
between(0, 10, 2) // [3.333, 6.666]
between(-1, -1.5) // [-1.25]
between(4, 4, 99) // []

Source

/**
 * Gets a set of integers that are evenly distributed along a closed interval
 * @param {int} begin - Beginning endpoint (inclusive)
 * @param {int} end   - Ending endpoint (inclusive)
 * @return {Array} Range of integers
 */
function rangeInt( begin, end )  {
    if ( !Number.isInteger(begin) || !Number.isInteger(end) ) {
        throw new Error('All arguments must be integers')
    }
    return range(begin, end, Math.abs(end - begin) - 1)
}

/**
 * Gets a set of numbers that are evenly distributed along a closed interval
 * @param {Number} begin  - Beginning endpoint (inclusive)
 * @param {Number} end    - Ending endpoint (inclusive)
 * @param {int}    points - How many numbers to retrieve from the open interval
 * @return {Array} Range of numbers
 */
function range( begin, end, points ) {
    if ( begin !== end ) {
        return [ begin, ...between(begin, end, points), end ]
    }
    else if ( Number.isFinite(begin) ) {
        return [ begin ] // singleton set
    }
    else throw new Error('Endpoints must be finite')
}

/**
 * Gets a subset of numbers that are evenly distributed along an open interval
 * @param {Number} begin  - Beginning endpoint (exclusive)
 * @param {Number} end    - Ending endpoint (exclusive)
 * @param {int}    points - How many numbers to retrieve from the interval
 * @return {Array} Retrieved numbers
 */
function between( begin, end, points = 1 ) {
    if ( !Number.isFinite(begin) || !Number.isFinite(end) || !Number.isFinite(points) ) {
        throw new Error('All arguments must be finite')
    }
    const set = []
    // Skip if an open interval does not exist
    if ( begin !== end ) {
        const step = (end - begin) / (points + 1)
        for ( let i = 0; i < points; i++ ) {
            set[i] = begin + (i + 1) * step
        }
    }
    return set
}
猥琐帝 2024-12-21 16:19:26

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 因为它解决了我的所有问题都涉及占用空间小且语法易于理解。对我来说,它是一个框架中 jQuery、MustacheJS 和 Underscore/SugarJS 的替代品。

当然,它不像下划线那么流行。这可能是一些人担心的问题。

Minified 由 Tim Jansen 使用 CC-0(公共领域)许可证提供。

Adding http://minifiedjs.com/ to the list of answers :)

Code is similar to underscore and others:

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 _()

Docs here:
http://minifiedjs.com/api/range.html

I use minified.js because it solves all my problems with low footprint and easy to understand syntax. For me, it is a replacement for jQuery, MustacheJS and Underscore/SugarJS in one framework.

Of course, it is not that popular as underscore. This might be a concern for some.

Minified was made available by Tim Jansen using the CC-0 (public domain) license.

_失温 2024-12-21 16:19:24

您可以设计一种范围方法,将“起始”数字增加所需的量,直到达到“结束”数字。
此示例将向上或向下“计数”,具体取决于 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;
    }   
}

如果你想以小数为单位步进:Array.range(0,1,.01)
您将需要截断任何浮点不精确的值。
否则你会返回像这样的数字
0.060000000000000005 而不是 0.06。

这给其他版本增加了一点开销,但对于整数或小数步可以正常工作。

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

You can design a range method that increments a 'from' number by a desired amount until it reaches a 'to' number.
This example will 'count' up or down, depending on whether from is larger or smaller than 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;
    }   
}

If you ever want to step by a decimal amount : Array.range(0,1,.01)
you will need to truncate the values of any floating point imprecision.
Otherwise you will return numbers like
0.060000000000000005 instead of .06.

This adds a little overhead to the other version, but works correctly for integer or decimal steps.

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;
    }   
}
金橙橙 2024-12-21 16:19:23
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;

可能有一种更干燥的方法来完成循环,但这是基本思想。

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;

There's probably a DRYer way to do the loop, but that's the basic idea.

浅唱ヾ落雨殇 2024-12-21 16:19:21
function createNumberArray(lowEnd, highEnd) {
    var start = lowEnd;
    var array = [start];
    while (start < highEnd) {
        array.push(start);
        start++;
    }
} 
function createNumberArray(lowEnd, highEnd) {
    var start = lowEnd;
    var array = [start];
    while (start < highEnd) {
        array.push(start);
        start++;
    }
} 
高冷爸爸 2024-12-21 16:19:21

如果开始总是小于结束,我们可以这样做:

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]

如果我们希望能够采用第三个参数来修改用于构建数组的步骤,并使其工作,即使开始大于end:

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。

If the start is always less than the end, we can do:

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]

If we want to be able to take a third argument to be able to modify the step used to build the array, and to make it work even though the start is greater than the end:

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]

This way the function accepts positive and negative steps and if no step is given, it defaults to 1.

原野 2024-12-21 16:19:19

我的五美分:

双向整数数组函数。

range(0, 5)变为[0, 1, 2, 3, 4, 5]时。

并且 range(5, 0) 变为 [5, 4, 3, 2, 1, 0]

基于这个答案。

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

PS 为了在现实生活中使用,您还应该检查 isFinite()isNaN() 的参数。

My five cents:

Both direction array of integers function.

When range(0, 5) become [0, 1, 2, 3, 4, 5].

And range(5, 0) become [5, 4, 3, 2, 1, 0].

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

P.S. For use in real life you should also check args for isFinite() and isNaN().

叶落知秋 2024-12-21 16:19:18

纯 ES6 的解决方案

受到上面 m59 答案的启发,但不依赖于 fill

const range = (start, stop) => Array.from({ length: stop - start + 1 }, (_, i) => start + i)

所以你可以像这样使用它:

range(3,5)
=> [3, 4, 5]

Solution with pure ES6

Inspired by m59's answer above, but without the dependency on fill:

const range = (start, stop) => Array.from({ length: stop - start + 1 }, (_, i) => start + i)

So you can use it like:

range(3,5)
=> [3, 4, 5]
无戏配角 2024-12-21 16:19:16
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);

这会创建一个具有正确标称长度的稀疏矩阵。现在稀疏矩阵的问题是,虽然它具有正确的标称长度,但它没有实际元素,因此, for

j = 7, k = 13

console.log(a);

给我们

Array [ <7 empty slots> ]

然后

var b = Array.apply(null, a);

将稀疏矩阵作为参数列表传递给 Array 构造函数,该构造函数生成一个稠密矩阵(实际) length targetLength,其中所有元素都有未定义的值。第一个参数是数组构造函数执行上下文的“this”值,在这里不起作用,因此为 null。

所以现在,

 console.log(b);

yields

 Array [ undefined, undefined, undefined, undefined, undefined, undefined, undefined ]

最终

var c = b.map(function(_, n){ return n + j; });

利用了 Array.map 函数将: 1. 当前元素的值和 2. 当前元素的索引传递给映射委托/回调的事实。第一个参数将被丢弃,而在调整起始偏移量后,第二个参数可用于设置正确的序列值。

那么

console.log(c);

产量

 Array [ 7, 8, 9, 10, 11, 12, 13 ]
function range(j, k) { 
    return Array
        .apply(null, Array((k - j) + 1))
        .map(function(_, n){ return n + j; }); 
}

this is roughly equivalent to

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

breaking it down:

var targetLength = (k - j) + 1;

var a = Array(targetLength);

this creates a sparse matrix of the correct nominal length. Now the problem with a sparse matrix is that although it has the correct nominal length, it has no actual elements, so, for

j = 7, k = 13

console.log(a);

gives us

Array [ <7 empty slots> ]

Then

var b = Array.apply(null, a);

passes the sparse matrix as an argument list to the Array constructor, which produces a dense matrix of (actual) length targetLength, where all elements have undefined value. The first argument is the 'this' value for the the array constructor function execution context, and plays no role here, and so is null.

So now,

 console.log(b);

yields

 Array [ undefined, undefined, undefined, undefined, undefined, undefined, undefined ]

finally

var c = b.map(function(_, n){ return n + j; });

makes use of the fact that the Array.map function passes: 1. the value of the current element and 2. the index of the current element, to the map delegate/callback. The first argument is discarded, while the second can then be used to set the correct sequence value, after adjusting for the start offset.

So then

console.log(c);

yields

 Array [ 7, 8, 9, 10, 11, 12, 13 ]
独﹏钓一江月 2024-12-21 16:19:15

最快的方式

  1. while-- 在大多数浏览器上更快
  2. 直接设置变量比推送

功能更快:

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://jsfiddle.net/W3CUn/

对于反对者

性能

http://jsperf.com/for-push-while-set/2

在 ie 和 中更快在 Firefox 中速度提高 3 倍

仅在 aipad air 上 for 循环速度稍快一些。

在 win8、osx10.8、ubuntu14.04、ipad、ipad air、ipod 上测试;

与 chrome,ff,ie,safari,移动 safari。

我想看看旧版 ie 浏览器的性能,其中 for 循环没有那么优化!

fastest way

  1. while-- is faster on most browsers
  2. direct setting a variable is faster than push

function:

var x=function(a,b,c,d){d=[];c=b-a+1;while(c--){d[c]=b--}return d},

theArray=x(lowEnd,highEnd);

or

var arr=[],c=highEnd-lowEnd+1;
while(c--){arr[c]=highEnd--}

EDIT

readable version

var arr = [],
c = highEnd - lowEnd + 1;
while ( c-- ) {
 arr[c] = highEnd--
}

Demo

http://jsfiddle.net/W3CUn/

FOR THE DOWNVOTERS

performance

http://jsperf.com/for-push-while-set/2

faster in ie and 3x faster in firefox

only on aipad air the for loop is a little faster.

tested on win8, osx10.8, ubuntu14.04, ipad, ipad air, ipod;

with chrome,ff,ie,safari,mobile safari.

i would like to see the performance on older ie browsers where the for loop isn't that optimized!

写给空气的情书 2024-12-21 16:19:10

我的循环版本;)

var lowEnd = 1;
var highEnd = 25;
var arr = [];
while(lowEnd <= highEnd){
   arr.push(lowEnd++);
}

My version of the loop ;)

var lowEnd = 1;
var highEnd = 25;
var arr = [];
while(lowEnd <= highEnd){
   arr.push(lowEnd++);
}
将军与妓 2024-12-21 16:19:09

在 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 来自 npm 在实际项目中。它甚至支持后退,这很酷。

In 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);

For completeness, here it is with an optional step parameter.

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

I would use range-inclusive from npm in an actual project. It even supports backwards steps, so that's cool.

第七度阳光i 2024-12-21 16:19:09

我强烈推荐下划线或低破折号库:

http://underscorejs.org/#range

(几乎完全兼容,显然 lodash 运行得更快,但下划线有更好的 doco 恕我直言)

_.range([start], stop, [step])

这两个库都有一堆非常有用的实用程序。

I highly recommend underscore or lo-dash libraries:

http://underscorejs.org/#range

(Almost completely compatible, apparently lodash runs quicker but underscore has better doco IMHO)

_.range([start], stop, [step])

Both libraries have bunch of very useful utilities.

空‖城人不在 2024-12-21 16:19:03
var list = [];
for (var i = lowEnd; i <= highEnd; i++) {
    list.push(i);
}
var list = [];
for (var i = lowEnd; i <= highEnd; i++) {
    list.push(i);
}
泪意 2024-12-21 16:19:03

ES6:

使用 Array.from (文档此处):

console.log(
   Array.from({length:5},(v,k)=>k+1)
)

ES6 :

Use Array.from (docs here):

console.log(
   Array.from({length:5},(v,k)=>k+1)
)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文