Как сгенерировать последовательность чисел / символов в javascript?
Есть ли способ генерировать последовательность символов или чисел в JavaScript?
Например, я хочу создать массив, который содержит восемь единиц. Я могу сделать это с помощью цикла for, но интересно, есть ли библиотека jQuery или функция javascript, которая может сделать это для меня?
23 ответа
Вы можете сделать свою собственную функцию многократного использования, я полагаю, для вашего примера:
function makeArray(count, content) {
var result = [];
if(typeof content == "function") {
for(var i = 0; i < count; i++) {
result.push(content(i));
}
} else {
for(var i = 0; i < count; i++) {
result.push(content);
}
}
return result;
}
Тогда вы можете сделать одно из следующих:
var myArray = makeArray(8, 1);
//or something more complex, for example:
var myArray = makeArray(8, function(i) { return i * 3; });
Вы можете попробовать его здесь, обратите внимание, что приведенный выше пример совсем не использует jQuery, поэтому вы можете использовать его без. Вы просто ничего не получаете из библиотеки за что-то вроде этого:)
Если вы используете более новый синтаксис Javascript, то же самое может быть достигнуто с помощью:
Array(8).fill(1)
Следующее тоже хорошо работает, но, как отмечают другие, ключевое слово "new" является избыточным.
new Array(8).fill(1)
Без цикла for вот решение:
Array.apply(0, Array(8)).map(function() { return 1; })
Объяснение следующее.
Array(8)
создает разреженный массив из 8 элементов, все undefined
, apply
трюк превратит его в плотный массив. Наконец, с map
мы заменим это undefined
(то же самое) значение 1
,
Один лайнер:
new Array(10).fill(1).map( (_, i) => i+1 )
Урожайность:
[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
Это самый простой на сегодняшний день
const sequence = [...Array(10).keys()]
console.log(sequence)
Output : [0,1,2,3,4,5,6,7,8,9]
2016 - Пришла функциональность современного браузера. Нет необходимости в jquery все время.
Array.from({length: 8}, (el, index) => 1);
Вы можете заменить функцию стрелки на простую функцию обратного вызова, чтобы охватить чуть более широкий диапазон поддерживаемых браузеров. По крайней мере, для меня это самый простой способ перебора инициализированного массива за один шаг.
Примечание: IE не поддерживается в этом решении, но для этого есть polyfill на developer.mozilla.org/...
Используя Jquery:
$.map($(Array(8)),function(val, i) { return i; })
Это возвращает:
[0, 1, 2, 3, 4, 5, 6, 7]
$.map($(Array(8)),function() { return 1; })
Это возвращает:
[1, 1, 1, 1, 1, 1, 1, 1]
range(start,end,step)
: С итераторами ES6
Вы можете легко создать range()
функция генератора, которая может функционировать как итератор. Это означает, что вам не нужно предварительно генерировать весь массив.
function * range ( start, end, step ) {
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 array = generate_array(1,10,2);
Но когда что-то требует итератор (или дает вам возможность использовать итератор), вы также можете легко его создать.
for ( const i of range(1, Number.MAX_SAFE_INTEGER, 7) ) {
console.log(i)
}
Последовательность - это поток, который вычисляет значение, когда это необходимо. Это требует только немного памяти, но больше процессорного времени, когда используются значения.
Массив - это список предварительно вычисленных значений. Это займет некоторое время, прежде чем можно будет использовать первое значение. И это требует много памяти, потому что все возможные значения последовательности должны храниться в памяти. И вы должны определить верхний предел.
Это означает, что в большинстве случаев не стоит создавать массив со значениями последовательности. Вместо этого лучше реализовать последовательность как реальную последовательность, которая ограничена только длиной слова процессора.
function make_sequence (value, increment)
{
if (!value) value = 0;
if (!increment) increment = function (value) { return value + 1; };
return function () {
let current = value;
value = increment (value);
return current;
};
}
i = make_sequence()
i() => 0
i() => 1
i() => 2
j = make_sequence(1, function(x) { return x * 2; })
j() => 1
j() => 2
j() => 4
j() => 8
Вот тест, в котором комментарий после каждой опции показывает среднее время тысячи запусков в мс:
let opt=[
'Array(n).fill().map((_,i)=>i)', // 2.71
'Array(n).fill().map(function(_,i){return i})', // 2.73
'let o=[];for(let i=0;i<1e5;i++)o[i]=i', // 3.29
'let o=[];for(let i=0;i<1e5;i++)o.push(i)', // 3.31
'let o=[];for(let i=0,n2=n;i<n2;i++)o[i]=i', // 3.38
'let o=[];for(let i=0;i<n;i++)o[i]=i', // 3.57
'Array.apply(null,Array(n)).map(Function.prototype.call.bind(Number))', // 3.64
'Array.apply(0,Array(n)).map((_,i)=>i)', // 3.73
'Array.apply(null,Array(n)).map((_,i)=>i)', // 3.77
'o2=[];for(let i=0;i<n;i++)o2[i]=i', // 4.42
'[...Array(n).keys]', // 7.07
'Array.from({length:n},(_,i)=>i)', // 7.13
'Array.from(Array(n),(_,i)=>i)', // 7.23
'o3=[];for(i3=0;i3<n;i3++)o3[i3]=i3' // 24.34
]
let n=1e5
opt.sort(()=>Math.random()-.5)
for(let opti of opt){
let t1=process.hrtime.bigint()
eval(opti)
let t2=process.hrtime.bigint()
console.log(t2-t1+'\t'+opti)
}
Цикл стал намного быстрее, когда я использовал блочные переменные вместо глобальных переменных.
Я использовал медианное время вместо среднего, потому что иногда один запуск может занять намного больше времени, чем обычные запуски, что искажает среднее время.
Я провел тест, какfor i in {1..1000};do node seqbench.js;done
, потому что когда я запускал скрипт только один раз, но запускал каждую опцию внутри скрипта 1000 раз, на него повлияла какая-то оптимизация, при которойfor
петли стали самыми быстрыми вариантами.
в простом решении ES6:
seq = (from, len, step = 1) => Array.from({length: len}, (el, i) => from + (i * step));
The fastest way to define an array of 8 1s is to define it-
var A= [1, 1, 1, 1, 1, 1, 1, 1];
// You'd have to need a lot of 1s to make a dedicated function worthwhile.
// Maybe in the Matrix, when you want a lot of Smiths:
Array.repeat= function(val, len){
for(var i= len, a= []; i--; ) a[i]= val;
return a;
}
var A= Array.repeat('Smith',100)
/* returned value: (String)
Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith, Smith
*/
Другой метод, для тех, кто педантичен с экономией памяти:
Array.apply(null, Array(3)).map(Function.prototype.call.bind(Number))
Это хороший вариант
var result = [];
for (var i = 1; i != 4; ++i) result.push(i)
проверьте здесь дополнительные параметры https://ariya.io/2013/07/sequences-using-javascript-array
var GetAutoNumber = exports.GetAutoNumber = (L) => {
let LeftPad = (number, targetLength) => {
let output = number + '';
while (output.length < targetLength) {
output = '0' + output;
}
return output;
}
let MaxNumberOfGivenLength = "";
for (let t = 0;t < L;t++) {
MaxNumberOfGivenLength = MaxNumberOfGivenLength + "9"
}
let StartTime = +new Date();
let Result = [];
let ReturnNumber;
for (let i = 1;i <= MaxNumberOfGivenLength;i++) {
Result.push(LeftPad(i, L))
}
for (let k = 0;k != 26;k++) {
for (let j = 0;j <= 999;j++) {
Result.push(String.fromCharCode(k + 65) + LeftPad(j, (L - 1)));
}
}
console.log(Result.length)
return Result;
}
GetAutoNumber(3)
Результат будет выглядеть так: 001-999, A01-A99... Z01-Z99.
Если, как и я, вы часто используете linspace, вы можете легко изменить свою версию linspace следующим образом:
function linSeq(x0, xN) {
return linspace(x0, xN, Math.abs(xN-x0)+1);
}
function linspace(x0, xN, n){
dx = (xN - x0)/(n-1);
var x = [];
for(var i =0; i < n; ++i){
x.push(x0 + i*dx);
}
return x;
}
Затем вы можете использовать linSeq в любом направлении, например, linSeq(2,4) генерирует 2,3,4, в то время как linSeq(4,2) генерирует 4,3,2.
Мне нравится этот.
function* generate() {
let index = 0;
while (true) {
index++;
yield String.fromCharCode(64 + index); //this will return from A, and for number yield the index only
}
}
const gen = generate();
console.log(gen.next().value); // A
console.log(gen.next().value); // B
console.log(gen.next().value); // C
Если вы хотите создать последовательность равных чисел, это элегантная функция для этого (решение, аналогичное другому ответу):
seq = (n, value) => Array(n).fill(value)
Если вы хотите создать последовательность последовательных чисел, начинающуюся с 0, это хороший вариант:
seq = n => n<1 ? [] : [0, ...seq(n-1).map(v => v+1)]
Его можно легко расширить для разных начальных значений и приращений:
seq = (n, start=0, inc=1) => n<1 ? [] : [start, ...seq(n-1, start, inc).map(v => v+inc)]
Метод машинописи на основе кода Ария Хидаят:
/**
* Generates sequence of numbers from zero.
* @ param {number} count Count of numbers in result array.
* @ return {Array<number>} Sequence of numbers from zero to (count - 1).
*/
public static sequence(count: number): Array<number>
{
return Array.apply(0, Array(count)).map((x, i) =>
{
return i;
});
}
Почему бы не просто объединить и разделить?
function seq(len, value)
{
// create an array
// join it using the value we want
// split it
return (new Array(len + 1)).join(value).split("");
}
seq(10, "a");
["a", "a", "a", "a", "a", "a", "a", "a", "a", "a"]
seq(5, 1);
["1", "1", "1", "1", "1"]
Генерация целочисленной последовательности - это то, что определенно должно быть более удобным в JavaScript. Вот рекурсивная функция возвращает целочисленный массив.
function intSequence(start, end, n = start, arr = []) {
return n === end ? arr.concat(n)
: intSequence(start, end, start < end ? n + 1 : n - 1, arr.concat(n));
}
$> intSequence(1, 1)
<- Array [ 1 ]
$> intSequence(1, 3)
<- Array(3) [ 1, 2, 3 ]
$> intSequence(3, -3)
<- Array(7) [ 3, 2, 1, 0, -1, -2, -3 ]