Em PHP, você pode fazer ...
range(1, 3); // Array(1, 2, 3)
range("A", "C"); // Array("A", "B", "C")
Ou seja, existe uma função que permite obter um intervalo de números ou caracteres passando os limites superior e inferior.
Existe algo embutido no JavaScript nativamente para isso? Caso contrário, como eu o implementaria?
$R
função, mas, além disso, acho que não.Array.from("ABC") //['A', 'B', 'C']
Essa é a coisa mais próxima que posso encontrar para a segunda parte da pergunta.split("")
tambémArray.apply(null, { length: 10 }).map(eval.call, Number)
Respostas:
Números
Iteração de caracteres
Iteração
Como funções
Como funções digitadas
_.range()
função lodash.jsNavegadores antigos não es6 sem uma biblioteca:
(Crédito ES6 a nils petersohn e outros comentadores)
fonte
(new Array(5)).map(function (value, index) { return index; })
não funcionaria? Isso retorna[undefined × 5]
para mim no DevTools do Chrome.map()
ou com um de seus amigos.Array(5).fill()
também éPara números, você pode usar o ES6
Array.from()
, que funciona em tudo hoje em dia, exceto no IE:Versão mais curta:
Versão mais longa:
que cria uma matriz de 0 a 19 inclusive. Isso pode ser reduzido ainda mais para uma destas formas:
Os limites inferior e superior também podem ser especificados, por exemplo:
Um artigo que descreve isso com mais detalhes: http://www.2ality.com/2014/05/es6-array-methods.html
fonte
Array.from()
método e mais rápido que ambos:Array(20).fill().map((_, i) => i)
Array.from({length: end - start}, (v, k) => k + start)
undefined
, portantofill()
(sem argumento) não está errado por si só. O valor de preenchimento não é usado nessa solução; portanto, se você quiser, podefill(0)
salvar alguns caracteres.Meu novo formulário favorito ( ES2015 )
E se você precisar de uma função com um
step
parâmetro:fonte
stop
não é realmente a posição de parada / fim, mas conta / distância. (sem ofensas, apenas para conscientizar as pessoas sobre o erro de digitação) #Array(Math.ceil((stop - start) / step) + 1)
, precisa+1
no final, realmente imitar o comportamento "inclusivo" do php.range
método. Todos os outros atualmente acima deste (exceto para lodash de_.range
) implementar iteradores básicas em vez de uma função de alcance real com iniciar, parar e passoAqui estão os meus 2 centavos:
fonte
Funciona para caracteres e números, avançando ou retrocedendo com uma etapa opcional.
jsFiddle .
Se você gosta de aumentar tipos nativos, atribua-o a
Array.range
.Mostrar snippet de código
fonte
Função de faixa simples:
Para incorporar o tipo de dados BitInt, algumas verificações podem ser incluídas, garantindo que todas as variáveis sejam iguais
typeof start
:Remover valores mais altos do que os definidos por
stop
exemplorange(0,5,2)
incluirá6
, o que não deveria ser.fonte
step != 1
, awhile
condição precisa levarstep
em consideração. Minha versão atualizada com umstep
valor padrão : range de funções (start, stop, step) {step = step || 1 var a = [início], b = início; while ((b + etapa) <parada) {console.log ("b:" + b + ". a:" + a + "."); b + = passo; a.push (b); } retornar a; }(step || 1)
,.fonte
Array
protótipo.undefined method toUpperCase to etc
:!OK, em JavaScript, não temos uma
range()
função como PHP , por isso precisamos criar a função que é bastante fácil, escrevo algumas funções de uma linha para você e as separo para Numbers e Alphabets, como abaixo:para números :
e chame assim:
para alfabetos :
e chame assim:
fonte
Array(end - start + 1)
eArray(end.charCodeAt(0) - start.charCodeAt(0) + 1)
.Função útil para executar o truque, execute o trecho de código abaixo
aqui está como usá-lo
range (Início, Fim, Passo = 1, Deslocamento = 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]
espero que você ache útil.
E aqui está como isso funciona.
Basicamente, estou primeiro calculando o comprimento da matriz resultante e criando uma matriz preenchida com zero nesse comprimento, depois preenchendo-a com os valores necessários
(step || 1)
=> E outros como este meio usar o valor dostep
e se não foi fornecido o uso1
em vez(Math.abs(end - start) + ((offset || 0) * 2)) / (step || 1) + 1)
para simplificar (diferença * deslocamento na direção / etapa)new Array(length).fill(0);
check aqui[0,0,0,..]
com o comprimento que queremos. Mapeamos sobre ele e retornamos uma nova matriz com os valores que precisamos usandoArray.map(function() {})
var direction = start < end ? 1 : 0;
Obviamente, sestart
não for menor do que oend
necessário, precisamos retroceder. Quero dizer, passando de 0 a 5 ou vice-versastartingPoint
+stepSize
*index
will nos fornece o valor que precisamosfonte
fonte
_
é apenas um nome de argumento no retorno de chamada de mapeamento. Você sabe, em alguns idiomas, você usaria o_
como um nome para indicar que a variável não é usada._
não é passado os argumentos pararange
. Por que não?Usando o operador de propagação Harmony e as funções de seta:
Exemplo:
fonte
--- ATUALIZAÇÃO (Agradecimentos a @lokhmakov pela simplificação) ---
Outra versão usando geradores ES6 (veja a excelente resposta de Paolo Moretti com geradores ES6 ):
Ou, se precisarmos apenas de iterável, então:
--- O código original era: ---
e
fonte
const range = (x, y) => Array.from(function* () { while (x <= y) yield x++; }())
Fiz algumas pesquisas sobre várias funções de intervalo. Confira a comparação do jsperf das diferentes maneiras de executar essas funções. Certamente não é uma lista perfeita ou exaustiva, mas deve ajudar :)
O vencedor é...
Tecnicamente, não é o mais rápido no Firefox, mas a louca diferença de velocidade (imho) no Chrome compensa isso.
Também é interessante observar o quão rápido o cromo é com essas funções de matriz do que o firefox. O Chrome é pelo menos 4 ou 5 vezes mais rápido .
fonte
O Javascript padrão não possui uma função interna para gerar intervalos. Várias estruturas javascript adicionam suporte para esses recursos ou, como outros já apontaram, você sempre pode criar seus próprios.
Se você deseja verificar novamente, o recurso definitivo é o padrão ECMA-262 .
fonte
Você pode usar lodash ou Undescore.js
range
:Como alternativa, se você precisar apenas de um intervalo consecutivo de números inteiros, poderá fazer algo como:
No ES6
range
pode ser implementado com geradores :Essa implementação economiza memória ao iterar grandes seqüências, porque não precisa materializar todos os valores em uma matriz:
fonte
Array.from
para converter geradores em instâncias de array e inspecionar a saída.Um desafio interessante seria escrever a função mais curta para fazer isso. Recursão ao resgate!
Tende a ser lento em grandes faixas, mas felizmente os computadores quânticos estão ao virar da esquina.
Um bônus adicional é que é ofuscante. Porque todos sabemos o quanto é importante ocultar nosso código de olhares indiscretos.
Para ofuscar verdadeira e totalmente a função, faça o seguinte:
fonte
const range = (a, b) => (a>=b) ? [] : [a, ...range(a+1, b)]
const range = (a, b, Δ = 1) => (a > b) ? [] : [a, ...range(a + Δ, b, Δ)];
. Também votando a resposta inteira para o comentário.Esta pode não ser a melhor maneira. Mas se você deseja obter um intervalo de números em uma única linha de código. Por exemplo 10 - 50
Onde 40 é (fim - começo) e 10 é o começo. Isso deve retornar [10, 11, ..., 50]
fonte
Eu codificaria algo como isto:
Ele se comporta de maneira semelhante ao intervalo do Python:
fonte
Uma implementação bastante minimalista que emprega fortemente o ES6 pode ser criada da seguinte maneira, chamando atenção especial para o
Array.from()
método estático:fonte
getRange()
espécie de função "aprimorada" . Em particular, pretendi capturar casos extremos que podem não ser tratados na variante básica acima. Além disso, adicionei suporte para intervalos alfanuméricos. Em outras palavras, chamá-lo com duas entradas fornecidas, como'C'
e'K'
(nessa ordem), retorna uma matriz cujos valores são o conjunto seqüencial de caracteres da letra 'C' (inclusive) através da letra 'K' (exclusiva):getRange('C', 'K'); // => ["C", "D", "E", "F", "G", "H", "I", "J"]
new
palavrarange(start,end,step)
: Com iteradores ES6Você só pede limites superior e inferior. Aqui nós criamos um com um passo também.
Você pode criar facilmente a
range()
função de gerador, que pode funcionar como um iterador. Isso significa que você não precisa pré-gerar toda a matriz.Agora você pode criar algo que pré-gera a matriz do iterador e retorna uma lista. Isso é útil para funções que aceitam uma matriz. Para isso, podemos usar
Array.from()
Agora você pode gerar uma matriz estática facilmente,
Mas quando algo deseja um iterador (ou oferece a opção de usar um iterador), você também pode facilmente criar um.
Notas especiais
R.range
, assim como o Lodashfonte
Embora isso não seja do PHP , mas uma imitação
range
do Python .fonte
Na medida em que gera uma matriz numérica para um determinado intervalo, eu uso o seguinte:
Obviamente, não funcionará para matrizes alfabéticas.
fonte
array = []
dentro do loop pode não dar o que você deseja.[5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
, eu esperaria apenas a primeira metade desse array.Usando geradores Harmony , suportados por todos os navegadores, exceto o IE11 :
Exemplos
toma
Exemplo 1.
take
leva apenas o máximo possíveltake(10, range( {from: 100, step: 5, to: 120} ) )
retorna
[100, 105, 110, 115, 120]
Exemplo 2
to
não necessáriotake(10, range( {from: 100, step: 5} ) )
retorna
[100, 105, 110, 115, 120, 125, 130, 135, 140, 145]
leve tudo
Exemplo 3
from
não necessáriotakeAll( range( {to: 5} ) )
retorna
[0, 1, 2, 3, 4, 5]
Exemplo 4
takeAll( range( {to: 500, step: 100} ) )
retorna
[0, 100, 200, 300, 400, 500]
Exemplo 5
takeAll( range( {from: 'z', to: 'a'} ) )
retorna
["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"]
fonte
for
cláusula melhoraria a legibilidade aqui.... mais alcance, usando uma função de gerador.
Espero que isso seja útil.
fonte
Meu colega de trabalho de codegolfe veio com isso (ES6), inclusive:
não inclusivo:
fonte
você pode usar a
lodash
função_.range(10)
https://lodash.com/docs#rangefonte
O d3 também possui uma função de alcance embutida. Consulte https://github.com/mbostock/d3/wiki/Arrays#d3_range :
Exemplo:
fonte
Implementação completa do ES6 usando a assinatura de intervalo ([start,] stop [, step]):
Se você quiser um passo negativo automático, adicione
Ou mais minimalisticamente:
Se você tem grandes faixas, observe a abordagem de gerador de Paolo Moretti
fonte
!stop
portypeof stop === 'undefined'
, substituaint
porMath.floor
e adicione uma verificaçãoif (start > stop && step > 0)
(caso contrário,range(-3, -10)
lança uma exceção em vez de fazer algo sensato (inverter o sinal da etapa ou retornar[]
)). Caso contrário, bom!Existe um módulo npm bereich para isso ("bereich" é a palavra alemã para "range"). Utiliza os iteradores modernos do JavaScript, para que você possa usá-lo de várias maneiras, como:
Ele também suporta intervalos descendentes (simplesmente trocando
min
emax
) e também suporta outras etapas que não1
.Isenção de responsabilidade: eu sou o autor deste módulo; portanto, responda com um grão de sal.
fonte
Este também funciona ao contrário.
fonte