si potrebbe noi e reduce
come questo, che restituirà la chiave del primo valore più piccolo d
:
reduce((x, y) -> d[x] ≤ d[y] ? x : y, keys(d))
Questo funziona solo per non vuote Dict
s, però. (Ma la nozione di “chiave del valore minimo di nessun valore” non ha molto senso, in modo che di solito caso dovrebbe essere gestita separatamente in ogni caso.)
Modifica per quanto riguarda l'efficienza.
considerare queste definizioni (nessuno dei quali gestisce collezioni vuote) ...
m1(d) = reduce((x, y) -> d[x] ≤ d[y] ? x : y, keys(d))
m2(d) = collect(keys(d))[indmin(collect(values(d)))]
function m3(d)
minindex(x, y) = d[x] ≤ d[y] ? x : y
reduce(minindex, keys(d))
end
function m4(d)
minkey, minvalue = next(d, start(d))[1]
for (key, value) in d
if value < minvalue
minkey = key
minvalue = value
end
end
minkey
end
... con questo codice:
function benchmark(n)
d = Dict{Int, Int}(1 => 1)
m1(d); m2(d); m3(d); m4(d); m5(d)
while length(d) < n
setindex!(d, rand(-n:n), rand(-n:n))
end
@time m1(d)
@time m2(d)
@time m3(d)
@time m4(d)
end
Calling benchmark(10000000)
stamperà qualcosa di simile:
1.455388 seconds (30.00 M allocations: 457.748 MB, 4.30% gc time)
0.380472 seconds (6 allocations: 152.588 MB, 0.21% gc time)
0.982006 seconds (10.00 M allocations: 152.581 MB, 0.49% gc time)
0.204604 seconds
Da questo possiamo vedere che m2
(da user3580870's answer) è effettivamente più veloce della mia soluzione originale m1
da un fattore di circa 3 a 4 e utilizza anche meno memoria. Ciò è apparentemente dovuto alla funzione di overhead delle chiamate, ma anche al fatto che l'espressione λ in m1
non è ottimizzata molto bene. Siamo in grado di alleviare il secondo problema definendo una funzione di supporto come in m3
, che è meglio di m1
, ma non buono come m2
.
Tuttavia, m2
assegna ancora O (n) memoria, che può essere evitato: se si ha realmente bisogno l'efficienza, è necessario utilizzare un ciclo esplicito come in m4
, che assegna quasi nessun memoria ed è anche più veloce.
'indmin()' o 'findmin()' dovrebbe funzionare. Non so perché 'minimum()' fa la cosa sbagliata ... – daycaster
'findmin' non funziona in realtà; dà anche uno strano risultato in questo caso: '(1 => 20,16)' –
@ DavidP.Sanders Strange, ottengo (10,2). – daycaster