2009-06-24 19 views
6

मैं Learn You a Haskell के माध्यम से पढ़ रहा हूं और उस स्थान पर पहुंचा जहां मैं एक सूची में एक तत्व में सिर को स्थानांतरित करने की कोशिश कर रहा हूं। मैं जो सोचता हूं उसके साथ मैं आभारी हूं और मैं उत्सुक हूं कि कोई मुझे दिखा सकता है कि अनुभवी हास्केल प्रोग्रामर इसके बदले क्या करेगा।हास्केल में किसी सूची में तत्व को कैसे स्थानांतरित करें?

इस उदाहरण में, मेरे पास इंटेगर्स की एक सूची है और मैं तत्व '4' को स्थानांतरित करना चाहता हूं, जो सूची के प्रमुख को सूचकांक '3' होगा।

let nums = [1, 2, 3, 4, 5] 
(nums !! 3) : delete (nums !! 3) nums 

रिटर्न [4, 1, 2, 3, 5]।

आपको क्या लगता है?

+3

"हटाएँ" का मिलान पद्धति का उपयोग कर दिया तत्व की पहली आवृत्ति को हटा देता है, तो यह गलत तत्व निकाल सकता है देखते हैं अगर डुप्लिकेट ... – sth

उत्तर

15

मैं इसे इस तरह से करना होगा:

move n as = head ts : (hs ++ tail ts) 
    where (hs, ts) = splitAt n as 

splitAt दी गई स्थिति एक सूची विभाजन, यह दो भागों बंटवारे (यहाँ hs और ts) द्वारा बनाई गई हैं कि देता है। तत्व जो मोर्चे पर ले जाया जाना चाहिए अब ts की शुरुआत में है। head tsts, tail ts का यह पहला तत्व देता है लेकिन वह पहला तत्व देता है। फ़ंक्शन का परिणाम केवल इन भागों को सही क्रम में मिला है: hstail ts के साथ संयोजित और head ts तत्व द्वारा अनुशंसित।

+3

toHead n l = let (xs, y: ys) = split y में y l: xs ++ ys – Stephan202

+0

sth: क्या आप कोड को समझने के लिए इसका वर्णन कर सकते हैं? – shahkalpesh

0

क्या सह-घटनाएं हैं?
मैं कुछ दिनों पहले एक ही चीज़ पढ़ रहा था। इसे फिर से देखा & इसे निम्नलिखित की तरह लिखा था।

nums !! 3 : [x | x <- nums, (x == (num !! 3)) == False] 
+0

दो समस्याएं: सबसे पहले, डुप्लिकेट तत्व हटा दिए जाते हैं। दूसरा (एक समस्या से कम), बराबर ऑपरेटर नहीं है (/ =), के विपरीत ((ए == बी) == गलत)। –

+0

अच्छा पकड़ो। जैसा कि आप देख सकते हैं, मैं एक नौसिखिया हूँ।सुधारने के लिए धन्यवाद :) – shahkalpesh

11

अनुभवी हास्केलर्स शायद ही कभी सूची अनुक्रमण का उपयोग कर अनुभव कर रहे हैं। मैं ब्रेक का उपयोग करेंगे दोहराया traversals से बचने के लिए (यह मानते हुए आप तत्व पर मेल करना चाहते हैं '4', नहीं सूचकांक '3'):

case break (== 4) [1, 2, 3, 4, 5] of 
    (a,x:xs) -> x:a ++ xs 
    (a,xs) -> a ++ xs 

में के रूप में:

Prelude Data.List> case break (== 4) [1, 2, 3, 4, 5] of (a,x:xs) -> x:a ++ xs; (a,xs) -> a ++ xs 
[4,1,2,3,5] 

हम भी ऐसा कर सकते 'splitAt' के माध्यम से अनुक्रमण के साथ:

Prelude Data.List> case splitAt 3 [1, 2, 3, 4, 5] of (a,x:xs) -> x:a ++ xs; (a,xs) -> a ++ xs 
[4,1,2,3,5] 
+0

हां, यह तत्व 4 पर मेल नहीं खा रहा है सूचकांक '3' पर। भ्रम के लिए खेद है – afrosteve

3

वहाँ भी

toHead n l = l !! n : take n l ++ drop (n+1) l 
है

जो splitAt का उपयोग करने से पालन करने के लिए थोड़ा आसान हो सकता है।

+0

विभाजन के संस्करण से धीमा नहीं है? – yairchu

+0

ऑप्टिमाइज़र इसके साथ होने के बाद स्पष्ट नहीं है। Ghc -O के साथ भागो और पता लगाना! –

+0

क्या यह सूची में 2 पास होगा? – Daniel

8

sth के समाधान के छोटा सा संशोधन:

toHead n xs = x : pre ++ post 
    where (pre, x:post) = splitAt n xs 

बजाय head n tail

+1

मुझे लगता है कि समाधान को समझना सबसे आसान है। पैटर्न मिलान के साथ अच्छा स्पर्श! – Michael

संबंधित मुद्दे