2014-07-21 16 views
6

के सभी इंडेक्स लौटें क्या एक बड़ी स्ट्रिंग (स्रोत) के भीतर एक सबस्ट्रिंग (लक्ष्य) के लिए सभी इंडेक्स की एक सूची प्राप्त करने के लिए एक स्कैला लाइब्रेरी एपीआई विधि (और यदि नहीं, एक मूर्खतापूर्ण तरीका) है? मैंने ScalaDoc को देखने की कोशिश की है, लेकिन कुछ भी स्पष्ट नहीं मिला। इतनी सारी उपयोगी चीजें करने के कई तरीके हैं, मुझे लगता है कि मैं सिर्फ सही खोज शब्द सबमिट नहीं कर रहा हूं।किसी विशेष सबस्ट्रिंग

उदाहरण के लिए, यदि मेरे पास "नाम: यो, नाम: जिम, नाम: नाम, नाम: बोझो" का स्रोत स्ट्रिंग है और मैं "नाम:" की एक लक्षित स्ट्रिंग का उपयोग करता हूं, तो मैं वापस प्राप्त करना चाहता हूं सूची [Int] सूची (0, 8, 17, 27)।

def indexesOf(source: String, target: String, index: Int = 0, withinOverlaps: Boolean = false): List[Int] = { 
    def recursive(index: Int, accumulator: List[Int]): List[Int] = { 
     if (!(index < source.size)) accumulator 
     else { 
     val position = source.indexOf(target, index) 
     if (position == -1) accumulator 
     else { 
      recursive(position + (if (withinOverlaps) 1 else target.size), position :: accumulator) 
     } 
     } 
    } 

    if (target.size <= source.size) { 
     if (!source.equals(target)) { 
     recursive(0, Nil).reverse 
     } 
     else List(0) 
    } 
    else Nil 
    } 

किसी भी मार्गदर्शन तुम मुझे एक उचित मानक पुस्तकालय प्रवेश बिंदु के साथ इस जगह बहुत सराहना की जाएगी दे सकते हैं:

यहाँ समस्या को हल करने के लिए अपने त्वरित हैक है।

अद्यतन 2014/Jul/22:

सिद्धार्थ दत्ता की जवाब से प्रेरित होकर, मैं मेरे कोड tighted। इसके अतिरिक्त

def indexesOf(source: String, target: String, index: Int = 0, withinOverlaps: Boolean = false): List[Int] = { 
    @tailrec def recursive(indexTarget: Int, accumulator: List[Int]): List[Int] = { 
     val position = source.indexOf(target, indexTarget) 
     if (position == -1) accumulator 
     else 
     recursive(position + (if (withinOverlaps) 1 else target.size), position :: accumulator) 
    } 
    recursive(index, Nil).reverse 
    } 

, अगर मैं "aaaaaaaa" का एक स्रोत स्ट्रिंग है और मैं "आ" का लक्ष्य स्ट्रिंग का उपयोग, मैं डिफ़ॉल्ट रूप से पसंद वापस एक सूची [इंट] की प्राप्त करने के लिए होगा: अब यह इस तरह दिखता है सूची (0, 2, 4, 6) जो एक पाए गए सबस्ट्रिंग के अंदर एक खोज शुरू करती है। डिफ़ॉल्ट ओवरऑप्स पैरामीटर के लिए "सत्य" पास करके डिफ़ॉल्ट को ओवरराइड किया जा सकता है, जिसमें "aaaaaaaa"/"aa" केस सूची (0, 1, 2, 3, 4, 5, 6) वापस आ जाएगा।

+1

नहीं, "एक [मानक] विधि" नहीं है पाने के लिए। साथ ही, चूंकि यह कोड काम कर रहा है, इसलिए यह * कोड-समीक्षा के लिए अधिक उपयुक्त हो सकता है। – user2864740

+0

@ chaotic3quilibrium किसी भी तरह से आप बीएसडी लाइसेंस कर सकते हैं कि जिस तरह से बॉस मैन मुझ पर पागल नहीं होता है अगर मैं इसे कॉपी/अनुकूलित करता हूं? :) – ericpeters

+0

@ericpeters यह मेरी समझ है कि StackOverflow पर यहां पोस्ट किए गए किसी भी कोड स्निपेट को अनिवार्य रूप से सार्वजनिक डोमेन माना जा सकता है; यानी किसी भी लाइसेंस बाधाओं से अनगिनत, जो भी आपको आवश्यक संदर्भ में स्निपेट को काट/पेस्ट/संशोधित/अनुकूलित करने की क्षमता को सीमित करता है। – chaotic3quilibrium

उत्तर

6

मैं हमेशा इस तरह की समस्याओं के साथ रेगेक्स चाल के बैग में पहुंचने के इच्छुक हूं। मैं नहीं कहूंगा कि यह उचित है, लेकिन यह बहुत कम कोड का नरक है। :)

val r = "\\Qname\\E".r 
val ex = "name:Yo,name:Jim,name:name,name:bozo" 

val is = r.findAllMatchIn(ex).map(_.start).toList 

उद्धरण \\Q और \\E इस मामले के लिए आवश्यक नहीं हैं, लेकिन अगर स्ट्रिंग आप देख रहे हैं कोई विशेष वर्ण है, तो यह हो जाएगा।

+0

एक प्रकार वापस करने में मददगार होगा। मैंने अपना कोड स्कैला मारने से पहले रेगेक्स दृष्टिकोण का मूल्यांकन करने में दो मिनट से भी कम समय बिताया। स्ट्रिंग सर्च बिल्ली को त्वचा से एक से अधिक तरीके से रखना अच्छा लगता है। – chaotic3quilibrium

+0

बीटीडब्ल्यू, आप पहली पंक्ति को \ "\ Qname \ E" "" "में भी बदल सकते हैं। आर अगर आप शुद्ध रेगेक्स (किसी अन्य स्रोत से एक अनपेक्षित प्रति/पेस्ट के रूप में) का उपयोग करना चाहते हैं। स्कैला में ट्रिपल कोट्स विकल्प शानदार है! – chaotic3quilibrium

1

एक छोटा सा कोड सभी अनुक्रमित
कॉल getAllIndexes नीचे के रूप में विधि (स्रोत, लक्ष्य)

def getAllIndexes(source: String, target: String, index: Int = 0): List[Int] = { 
     val targetIndex = source.indexOf(target, index) 
     if(targetIndex != -1) 
      List(targetIndex) ++ getAllIndexes(source, target, targetIndex+1) 
     else 
      List() 
     } 
+0

यह सूची को रिवर्स ऑर्डर में वापस करने के लिए प्रतीत होता है, यानी सूची (27, 17, 8, 0), है ना? इसके अतिरिक्त, यदि आप मार्गों को दो अनुकूलित कर सकते हैं। पहली जगह "सूची (लक्ष्य इंडेक्स) ++ प्राप्त करें ..." "targetIndex :: get ..." के साथ। और दूसरा "नील" के साथ "सूची()" को बदल रहा है। – chaotic3quilibrium

+1

कोई विधि इंडेक्स के अनुसार आरोही क्रम में सूची को वापस नहीं करती है, सूची (0,8,17,27)। अनुकूलन सही हैं। –

+0

मैंने अभी आपकी कॉल करने की कोशिश की है और @tailrec एनोटेशन जोड़ने के बाद, मुझे एक कंपाइलर त्रुटि मिल रही है जिसमें कहा गया है कि यह पूंछ रिकर्सिव नहीं है (या तो ++ या: :) के साथ। हालांकि, आपके छोटे कोड ने मुझे प्रेरित किया, इसलिए मैंने अपना कोड कसने के लिए एक अद्यतन प्रदान किया। वैकल्पिक वैकल्पिक ओवरराप्स पैरामीटर के लाभ को दिखाने के लिए मैंने एक और टेस्ट केस ("aaaaaaaa", "aa" उदाहरण) भी जोड़ा। – chaotic3quilibrium

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