Sök…


Syntax

  • förhand (f, xs)
  • karta (f, xs)
  • filter (f, xs)
  • minska (f, v0, xs)
  • vika (f, v0, xs)
  • foldr (f, v0, xs)

Anmärkningar

Funktioner kan accepteras som parametrar och kan också produceras som returtyper. Faktum är att funktioner kan skapas i kroppen för andra funktioner. Dessa inre funktioner kallas stängningar .

Funktioner som argument

Funktioner är föremål i Julia. Liksom alla andra objekt kan de skickas som argument till andra funktioner. Funktioner som accepterar funktioner kallas funktioner med högre ordning .

Till exempel kan vi implementera en motsvarighet till standardbibliotekets foreach funktion genom att ta en funktion f som den första parametern.

function myforeach(f, xs)
    for x in xs
        f(x)
    end
end

Vi kan testa att den här funktionen verkligen fungerar som vi förväntar oss:

julia> myforeach(println, ["a", "b", "c"])
a
b
c

Genom att ta en funktion som den första parametern, istället för en senare parameter, kan vi använda Julias do-block-syntax. Syntaxen för do block är bara ett bekvämt sätt att skicka en anonym funktion som det första argumentet till en funktion.

julia> myforeach([1, 2, 3]) do x
           println(x^x)
       end
1
4
27

Vår implementering av myforeach ovan motsvarar ungefär den inbyggda foreach funktionen. Många andra inbyggda funktioner i högre ordning finns också.

Funktioner med högre ordning är ganska kraftfulla. Ibland, när man arbetar med högre ordningsfunktioner, blir exakta operationer som är obetydliga och program kan bli ganska abstrakta. Kombinationer är exempel på system med mycket abstrakta funktioner med högre ordning.

Karta, filtrera och minska

Två av de mest grundläggande funktionerna med högre ordning som ingår i standardbiblioteket är map och filter . Dessa funktioner är generiska och kan fungera på vilken som helst iterable . I synnerhet är de väl lämpade för beräkningar på matriser .

Anta att vi har en datasats med skolor. Varje skola undervisar i ett visst ämne, har ett antal klasser och ett genomsnittligt antal elever per klass. Vi kan modellera en skola med följande immutable typ :

immutable School
    subject::Symbol
    nclasses::Int
    nstudents::Int  # average no. of students per class
end

Vårt datasats med skolor kommer att vara en Vector{School} :

dataset = [School(:math, 3, 30), School(:math, 5, 20), School(:science, 10, 5)]

Anta att vi vill hitta antalet studenter som totalt är inskrivna i ett matematikprogram. För att göra detta kräver vi flera steg:

  • vi måste begränsa datasatsen till endast skolor som undervisar i matematik ( filter )
  • vi måste beräkna antalet elever på varje skola ( map )
  • och vi måste reducera listan över antalet studenter till ett enda värde, summan ( reduce )

En naiv (inte mest performant) lösning skulle helt enkelt vara att använda dessa tre högre ordningsfunktioner direkt.

function nmath(data)
    maths = filter(x -> x.subject === :math, data)
    students = map(x -> x.nclasses * x.nstudents, maths)
    reduce(+, 0, students)
end

och vi verifierar att det finns 190 matteelever i vårt datasystem:

julia> nmath(dataset)
190

Det finns funktioner för att kombinera dessa funktioner och därmed förbättra prestandan. Vi kunde till exempel ha använt mapreduce funktionen för att utföra kartläggning och reduktion i ett steg, vilket skulle spara tid och minne.

reduce är endast meningsfull för associerande operationer som + , men ibland är det användbart att utföra en reduktion med en icke-associerande operation. Funktionerna högre ordning foldl och foldr tillhandahålls för att tvinga fram en viss reduktionsordning.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow