खोज…


वाक्य - विन्यास

  • शुरू (आईटीआर)
  • अगला (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"
0.5.0

गुणन तालिका बनाना

आइए मैट्रिक्स बनाने के लिए आलसी पुनरावृत्ति कार्यों का उपयोग करके एक गुणन तालिका बनाएं।

यहाँ उपयोग करने के लिए मुख्य कार्य हैं:

  • 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 पैकेज का उपयोग करना बेहतर है। हालांकि, शेड के ऊपर आलसी सूची का कार्यान्वयन महत्वपूर्ण विवरणों में रोशनी करता है कि किसी के स्वयं के चलने योग्य प्रकार का निर्माण कैसे करें।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow