javascript - gör <något> N gånger (deklarativ syntax)


Finns det ett sätt i Javascript att skriva något som detta lätt:

[1,2,3].times do {
  something();
}

Finns det något bibliotek som kanske kan stödja någon liknande syntax?

Uppdatering: för att förtydliga - jag vill att something() ska anropas 1, 2 och 3 gånger respektive för varje array-element i iterationen

Svar #1

Använd bara en for-loop:

const times = 10;

for(let i = 0; i < times; i++){
    doSomething();
}

Svar #2

Möjligt ES6-alternativ.

Array.from(Array(3)).forEach((x, i) => {
  something();
});

Och om du vill att det ska ”kallas 1, 2 och 3 gånger respektive”.

Array.from(Array(3)).forEach((x, i) => {
  Array.from(Array(i+1)).forEach((x, i2) => {
    console.log(`Something ${ i } ${ i2 }`)
  });
});

Uppdatering :

Tagen från filling-arrays-with-undefined

Detta verkar vara ett mer optimerat sätt att skapa den initiala arrayen, jag har också uppdaterat detta för att använda den andra parameterfunktionens kartfunktion som föreslogs av @felix-eve.

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

Svar #3

Det enklaste sättet är genom att destrukturera arrayen,

vilket automatiskt anger undefined för varje objekt, om objektets värde inte var satt:

[...Array(5)].map((item, i) => console.log(item, i))

Metoden keys för Array kan också användas för att generera en Array av indexvärden:

[...Array(3).keys()] // [0, 1, 2]

Alternativt, skapa en Array och fill alla item med undefined innan du använder map:

👉 Läs detaljerad förklaring till varför map hoppar över aldrig definierade array-element

⚠️ Array.fill har ingen IE-support

Array(5).fill().map((item, i) => console.log(item, i))

Om du vill göra det ovanstående mer "deklarativt", skulle min för närvarande åsiktsbaserade lösning vara:

const iterate = times => callback => [...Array(times)].map((n,i) => callback(i))

iterate(3)(console.log)

Använder gammaldags (omvänd) loop:

// run 5 times:
for( let i=5; i--; )
   console.log(i) 

Eller som ett deklarativt "while":

const run = (cb, ...args) => count => { while(count--) cb(...args) }

// executes the callback with whatever arguments, 3 times
run(console.log, 1,2,3)(3)

Svar #4

Detta svar baseras på Array.forEach, utan något bibliotek, bara native vanilla.

För att i princip kalla something() 3 gånger, använd:

[1,2,3].forEach(function(i) {
  something();
});

med tanke på följande funktion:

function something(){ console.log('something') }

Utdata kommer att vara:

something
something
something

För att slutföra dessa frågor, här är ett sätt att anropa something() 1, 2 och 3 gånger respektive:

Det är 2017, du kan använda ES6:

[1,2,3].forEach(i => Array(i).fill(i).forEach(_ => {
  something()
}))

eller i den gamla goda ES5:

[1,2,3].forEach(function(i) {
  Array(i).fill(i).forEach(function() {
    something()
  })
}))

I båda fallen kommer resultatet att vara

Utdata kommer att vara:

something

something
something

something
something
something

(en gång, sedan två gånger, sedan tre gånger)

Svar #5

Med lodash:

_.each([1, 2, 3], (item) => {
   doSomeThing(item);
});

//Or:
_.each([1, 2, 3], doSomeThing);

Eller om du vill göra något N gånger:

const N = 10;
_.times(N, () => {
   doSomeThing();
});

//Or shorter:
_.times(N, doSomeThing);

Svar #6

Eftersom du nämner Underscore:

Förutsatt att f är funktionen du vill kalla:

_.each([1,2,3], function (n) { _.times(n, f) });

kommer att göra susen. Till exempel, med f=function (x) { console.log(x); }, kommer du att få i din konsol: 0 0 1 0 1 2

Svar #7

Du kan också göra samma sak med destrukturering på följande sätt

[...Array(3)].forEach( _ => console.log('do something'));

eller om du behöver index

[...Array(3)].forEach(( _, index) => console.log('do something'));

Svar #8

Vad sägs om en enkel medan.

let times = 5;

while (times--) {

    console.log(times+1)

}

Referenser om hur detta fungerar: Falsy och Dekrement (--)


Redigera: Om det finns en möjlighet att times kan manipuleras någon annanstans, är det säkrare att använda times-- > 0 istället för times-- för att förhindra en oändlig loop om times sjunker under 0

Relaterade artiklar