På mitt förra jobb använde vi ett programmeringsspråk (APL) som var klumpigt. Men det var också gymt smidigt på vissa sätt. När jag lärde mig att använda det på rätt sätt, förändrades också det sätt jag programmerade på i andra språk. Jag började använda funktionell programmering.
Nu ska jag inte lära dig APL, så vi tittar på hur man kan göra i Python istället. Låt säga att vi har en lista med strängar som vi ska göra till gemener:
myList = ['Måndag', 'tisdag', 'ONSdag', 'TORSDAG', 'freDag', 'LörDag', 'sönDAG']
Med en for-loop kan man lösa det exempelvis så här:
for i in range(len(myList)):
myList[i] = myList[i].lower()
Det är förstås inget fel med denna lösning, men det finns snyggare och snabbare sätt.
Map
def lower(s):
return s.lower()
myList = map(lower, myList)
Den inbyggda funktionen map kör funktionen lower på alla element i listan myList och returnerar en ny lista. Men det blir bättre!
Anonyma funktioner med lambda
Konstruktionen lambda i Python gör det möjligt att skapa anonyma enrads-funktioner. Det är lite onödigt att behöva definiera funktionen lower ovan bara för att användas i map-uttrycket, så vi använder lambda istället:
lower = lambda s: s.lower() myList = map(lower, myList)
Nu har vi satt variabeln lower till en funktion som tar ett argument och returnerar värdet från argumentets metod lower. (Lambda-funktioner returnerar automatiskt värdet, så man behöver inte skriva return.)
Men vi måste såklart inte tilldela en variabel funktionen , så vi gör så här istället:
myList = map(lambda s: s.lower(), myList)
Överkurs: list comprehension
I Python och vissa andra språk går det också att använda list comprehension för att göra samma sak:
myList = [s.lower() for s in myList]
Filter och reduce
Förutom funktionen map finns också de mycket användbara filter och reduce. Låt säga att vi vill plocka fram alla dagar ur listan som slutar på ”-sdag”. Då använder vi filter för att filtrera listan. Endast de element för vilka funktionen returnerar sant tas med i den nya listan.
myList = filter(lambda s: s.lower().endswith('sdag'), myList)
Reduce används istället för att reducera en lista till ett enda värde. Det typiska användningsområdet är att göra någon matematisk operation på en lista av numeriska värden. Jag går inte in på det noggrannare här.
Motsvarigheter i PHP
Funktionerna heter i PHP array_map, array_filter och array_reduce. Tyvärr finns inte lambda, men från PHP 5.3 kan man istället skicka in hela funktionsdefinitioner som argument, på samma sätt som i Javascript. Läs mer här.
Motsvarigheter i Javascript
Från och med Javascript 1.6 finns metoderna Array.map och Array.filter, och från version 1.8 finns även Array.reduce. De stöds tyvärr bara i webbläsare som implementerat dessa versioner av Javascript, och jag vet inte riktigt vilka webbläsare det är. Någon som vet?