एक और अधिक सुरुचिपूर्ण कार्यात्मक समाधान:
let duplicates xs =
Seq.scan (fun xs x -> Set.add x xs) Set.empty xs
|> Seq.zip xs
|> Seq.choose (fun (x, xs) -> if Set.contains x xs then Some x else None)
का उपयोग करता है scan
अब तक देखा सभी तत्वों के सेट जमा करने के लिए। इसके बाद तत्वों के सेट के साथ प्रत्येक तत्व को गठबंधन करने के लिए zip
का उपयोग करता है। अंत में, choose
का उपयोग पहले से देखे गए तत्वों के सेट में मौजूद तत्वों को फ़िल्टर करने के लिए करता है, यानी डुप्लिकेट।
संपादित
असल में मेरी मूल जवाब पूरी तरह से गलत था। सबसे पहले, आप अपने आउटपुट में डुप्लीकेट नहीं चाहते हैं। दूसरा, आप प्रदर्शन चाहते हैं।
यहाँ एक पूरी तरह कार्यात्मक समाधान है कि एल्गोरिथ्म आप के बाद कर रहे हैं लागू करता है:
let duplicates xs =
(Map.empty, xs)
||> Seq.scan (fun xs x ->
match Map.tryFind x xs with
| None -> Map.add x false xs
| Some false -> Map.add x true xs
| Some true -> xs)
|> Seq.zip xs
|> Seq.choose (fun (x, xs) ->
match Map.tryFind x xs with
| Some false -> Some x
| None | Some true -> None)
यह ट्रैक करने के लिए है कि क्या प्रत्येक तत्व से पहले एक या कई बार देखा गया है किसी मैप का उपयोग करता है और उसके बाद ही वह तत्व का उत्सर्जन करता है देखा जाता है कि केवल एक बार पहले देखा जा रहा था, यानी पहली बार इसे डुप्लिकेट किया गया है।
let duplicates (xs: _ seq) =
seq { let d = System.Collections.Generic.Dictionary(HashIdentity.Structural)
let e = xs.GetEnumerator()
while e.MoveNext() do
let x = e.Current
let mutable seen = false
if d.TryGetValue(x, &seen) then
if not seen then
d.[x] <- true
yield x
else
d.[x] <- false }
यह आपके अन्य उत्तर में से किसी की तुलना में तेजी लगभग 2 × (लेखन के समय) है:
यहाँ एक तेजी से जरूरी संस्करण है।
एक क्रम में तत्वों की गणना करने में एक for x in xs do
पाश का उपयोग करना GetEnumerator
सीधे का उपयोग कर, लेकिन पैदा अपनी खुद की Enumerator
काफी yield
के साथ एक गणना अभिव्यक्ति का उपयोग कर की तुलना में तेजी नहीं है की तुलना में काफी धीमी है।
ध्यान दें कि Dictionary
की TryGetValue
सदस्य मुझे एक ढेर आवंटित मूल्य परिवर्तनशील जबकि TryGetValue
विस्तार सदस्य (उसकी/उसके जवाब में KVB द्वारा और प्रयोग किया जाता) एफ # द्वारा की पेशकश की अपनी वापसी टपल आवंटित द्वारा भीतरी पाश में आवंटन से बचने के लिए अनुमति देता है।
संभावित डुप्लिकेट [मैं संदर्भों का उपयोग किये बिना एफ # अनुक्रम में डुप्लीकेट कैसे हटा सकता हूं] (http://stackoverflow.com/questions/6842466/how-can-i-remove-duplicates-in-an-f-sequence -without-use-references) – gradbot
दरअसल, यह उलटा है। मैं केवल डुप्लिकेट चाहता हूं। – Daniel
हम्म, आप उन मूल्यों को कैसे स्टोर करना चाहते हैं जिन्हें आप पहले से देख चुके हैं? सेट? शब्दकोश? – gradbot