Julia Language
Iterables
खोज…
वाक्य - विन्यास
- शुरू (आईटीआर)
- अगला (itr, s)
- किया (itr, s)
- लेना (itr, n)
- ड्रॉप (आईटीआर, एन)
- चक्र (आईटीआर)
- Base.product (xs, ys)
पैरामीटर
पैरामीटर | विवरण |
---|---|
के लिये | सभी कार्य |
itr | संचालित करने के लिए चलने योग्य। |
के लिये | next और done |
s | पुनरावृति की वर्तमान स्थिति का वर्णन करते हुए एक पुनरावृत्त राज्य। |
के लिये | take और drop |
n | लेने या छोड़ने के लिए तत्वों की संख्या। |
के लिये | Base.product |
xs | से जोड़े के पहले तत्वों को लेने के लिए चलने योग्य। |
ys | से जोड़े के दूसरे तत्वों को लेने के लिए चलने योग्य। |
... | (ध्यान दें कि product किसी भी तर्क को स्वीकार करता है; यदि दो से अधिक प्रदान किए जाते हैं, तो यह दो से अधिक लंबाई के ट्यूपल का निर्माण करेगा।) |
नया चलने योग्य प्रकार
जूलिया में, जब एक iterable वस्तु के माध्यम से पाशन I
साथ किया जाता है for
वाक्य रचना:
for i = I # or "for i in I" # body end
पर्दे के पीछे, इसका अनुवाद इस प्रकार है:
state = start(I) while !done(I, state) (i, state) = next(I, state) # body end
इसलिए, यदि आप चाहते हैं कि I
एक पुनरावृत्त होना चाहता I
, तो आपको इसके प्रकार के लिए start
, next
और done
तरीकों को परिभाषित start
आवश्यकता है। मान लीजिए कि आप एक प्रकार को परिभाषित करते हैं, जिसमें फ़ील्ड के रूप में एक सरणी युक्त Foo
:
type Foo bar::Array{Int,1} end
हम एक Foo
वस्तु को तुरंत करते हैं:
julia> I = Foo([1,2,3])
Foo([1,2,3])
julia> I.bar
3-element Array{Int64,1}:
1
2
3
यदि हम Foo
माध्यम से पुनरावृति करना चाहते हैं, तो प्रत्येक पुनरावृत्ति द्वारा प्रत्येक तत्व bar
को वापस करने के साथ, हम विधियों को परिभाषित करते हैं:
import Base: start, next, done start(I::Foo) = 1 next(I::Foo, state) = (I.bar[state], state+1) function done(I::Foo, state) if state == length(I.bar) return true end return false end
ध्यान दें कि चूंकि ये फ़ंक्शन Base
मॉड्यूल से संबंधित हैं, इसलिए हमें नए तरीकों को जोड़ने से पहले पहले उनके नामों को import
करना होगा।
तरीकों को परिभाषित करने के बाद, Foo
इट्टरेटर इंटरफेस के साथ संगत है:
julia> for i in I println(i) end 1 2 3
आलसी Iterables का संयोजन
मानक पुस्तकालय आलसी पुनरावृत्तियों के एक समृद्ध संग्रह के साथ आता है (और Iterators.jl जैसे पुस्तकालय और भी अधिक प्रदान करते हैं)। आलसी पुनरावृत्तियों की रचना निरंतर समय में अधिक शक्तिशाली पुनरावृत्तियों को बनाने के लिए की जा सकती है। सबसे महत्वपूर्ण आलसी पुनरावृत्तियों को लेना और छोड़ना है , जिसमें से कई अन्य कार्य बनाए जा सकते हैं।
आलसी टुकड़ा एक पुनरावृत्ति
Arrays टुकड़ा संकेतन के साथ कटा जा सकता है। उदाहरण के लिए, निम्नलिखित में सरणी के 10 वें से 15 वें तत्व शामिल हैं:
A[10:15]
हालांकि, स्लाइस नोटेशन सभी पुनरावृत्तियों के साथ काम नहीं करता है। उदाहरण के लिए, हम एक जनरेटर अभिव्यक्ति को नहीं काट सकते:
julia> (i^2 for i in 1:10)[3:5]
ERROR: MethodError: no method matching getindex(::Base.Generator{UnitRange{Int64},##1#2}, ::UnitRange{Int64})
स्लाइसिंग स्ट्रिंग्स में अपेक्षित यूनिकोड व्यवहार नहीं हो सकता है:
julia> "αααα"[2:3]
ERROR: UnicodeError: invalid character index
in getindex(::String, ::UnitRange{Int64}) at ./strings/string.jl:130
julia> "αααα"[3:4]
"α"
हम एक समारोह lazysub(itr, range::UnitRange)
को मनमाने ढंग से पुनरावृत्तियों पर इस प्रकार का टुकड़ा करने के लिए परिभाषित कर सकते हैं। इसे take
एंड drop
संदर्भ में परिभाषित किया गया है:
lazysub(itr, r::UnitRange) = take(drop(itr, first(r) - 1), last(r) - first(r) + 1)
यहाँ कार्यान्वयन कार्य करता है क्योंकि UnitRange
मान a:b
, निम्न चरण किए गए हैं:
- पहले
a-1
तत्वों को गिरा देता है -
a
th तत्व,a+1
th तत्व, और इसके बाद,a+(ba)=b
th तत्व तक ले जाता है
कुल में, ba
तत्वों को लिया जाता है। हम पुष्टि कर सकते हैं कि ऊपर दिए गए प्रत्येक मामले में हमारा कार्यान्वयन सही है:
julia> collect(lazysub("αααα", 2:3))
2-element Array{Char,1}:
'α'
'α'
julia> collect(lazysub((i^2 for i in 1:10), 3:5))
3-element Array{Int64,1}:
9
16
25
आलस्यपूर्ण रूप से एक तिरछे बदलाव को स्थानांतरित करना
सरणियों पर circshift
ऑपरेशन सरणी को स्थानांतरित कर देगा जैसे कि यह एक सर्कल था, फिर इसे त्याग दें। उदाहरण के लिए,
julia> circshift(1:10, 3)
10-element Array{Int64,1}:
8
9
10
1
2
3
4
5
6
7
क्या हम यह आलसी सभी पुनरावृत्तियों के लिए कर सकते हैं? हम उपयोग कर सकते हैं cycle
, drop
, और take
iterables इस कार्यशीलता को लागू करने।
lazycircshift(itr, n) = take(drop(cycle(itr), length(itr) - n), length(itr))
आलसी प्रकार कई स्थितियों में अधिक प्रदर्शनशील होने के साथ, यह हमें उन प्रकारों पर circshift
-जैसी कार्यक्षमता करने देता है जो अन्यथा इसका समर्थन नहीं करेंगे:
julia> circshift("Hello, World!", 3)
ERROR: MethodError: no method matching circshift(::String, ::Int64)
Closest candidates are:
circshift(::AbstractArray{T,N}, ::Real) at abstractarraymath.jl:162
circshift(::AbstractArray{T,N}, ::Any) at abstractarraymath.jl:195
julia> String(collect(lazycircshift("Hello, World!", 3)))
"ld!Hello, Wor"
गुणन तालिका बनाना
आइए मैट्रिक्स बनाने के लिए आलसी पुनरावृत्ति कार्यों का उपयोग करके एक गुणन तालिका बनाएं।
यहाँ उपयोग करने के लिए मुख्य कार्य हैं:
-
Base.product
, जो कार्टेशियन उत्पाद की गणना करता है। -
prod
, जो एक नियमित उत्पाद की गणना करता है (गुणन में) -
:
, जो एक सीमा बनाता है -
map
, जो एक संग्रह के प्रत्येक तत्व के लिए एक फ़ंक्शन को लागू करने वाला एक उच्च क्रम फ़ंक्शन है
समाधान है:
julia> map(prod, Base.product(1:10, 1:10))
10×10 Array{Int64,2}:
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
आलसी-मूल्यांकन सूचियाँ
उत्परिवर्तित प्रकारों और क्लोजर का उपयोग करके एक सरल आलसी मूल्यांकन सूची बनाना संभव है। एक आलसी मूल्यांकन वाली सूची एक सूची है जिसके तत्वों का मूल्यांकन तब नहीं किया जाता है जब इसका निर्माण किया जाता है, बल्कि जब इसे एक्सेस किया जाता है। आलसी मूल्यांकन सूची के लाभों में अनंत होने की संभावना शामिल है।
import Base: getindex
type Lazy
thunk
value
Lazy(thunk) = new(thunk)
end
evaluate!(lazy::Lazy) = (lazy.value = lazy.thunk(); lazy.value)
getindex(lazy::Lazy) = isdefined(lazy, :value) ? lazy.value : evaluate!(lazy)
import Base: first, tail, start, next, done, iteratorsize, HasLength, SizeUnknown
abstract List
immutable Cons <: List
head
tail::Lazy
end
immutable Nil <: List end
macro cons(x, y)
quote
Cons($(esc(x)), Lazy(() -> $(esc(y))))
end
end
first(xs::Cons) = xs.head
tail(xs::Cons) = xs.tail[]
start(xs::Cons) = xs
next(::Cons, xs) = first(xs), tail(xs)
done(::List, ::Cons) = false
done(::List, ::Nil) = true
iteratorsize(::Nil) = HasLength()
iteratorsize(::Cons) = SizeUnknown()
जो वास्तव में हास्केल जैसी भाषा में काम करेगा, जहां सभी सूचियों का आलसी मूल्यांकन किया जाता है:
julia> xs = @cons(1, ys)
Cons(1,Lazy(false,#3,#undef))
julia> ys = @cons(2, xs)
Cons(2,Lazy(false,#5,#undef))
julia> [take(xs, 5)...]
5-element Array{Int64,1}:
1
2
1
2
1
व्यवहार में, यह Lazy.jl पैकेज का उपयोग करना बेहतर है। हालांकि, शेड के ऊपर आलसी सूची का कार्यान्वयन महत्वपूर्ण विवरणों में रोशनी करता है कि किसी के स्वयं के चलने योग्य प्रकार का निर्माण कैसे करें।