एक स्ट्रिंग में nth घटना कैसे प्राप्त करें?


104

मैं कुछ इस तरह से 2ndघटित होने की प्रारंभिक स्थिति प्राप्त करना चाहूंगा ABC:

var string = "XYZ 123 ABC 456 ABC 789 ABC";
getPosition(string, 'ABC', 2) // --> 16

आपको इसे कैसे करना होगा?


दूसरी घटना या आखिरी? :)
जेक

भ्रम के लिए क्षमा करें, मैं अंतिम इंडेक्स की तलाश में नहीं हूं। मैं nthइस घटना की शुरुआत की स्थिति की तलाश में हूं , इस मामले में दूसरी।
एडम

जवाबों:


158

const string = "XYZ 123 ABC 456 ABC 789 ABC";

function getPosition(string, subString, index) {
  return string.split(subString, index).join(subString).length;
}

console.log(
  getPosition(string, 'ABC', 2) // --> 16
)


26
मुझे वास्तव में यह उत्तर पसंद नहीं है। एक अनबाउंड लंबाई इनपुट को देखते हुए, यह अनावश्यक रूप से एक अनबाउंड लंबाई सरणी बनाता है, और फिर इसे दूर फेंकता है। यह तेजी से और अधिक कुशल होगा बस fromIndexतर्क का उपयोग करने के लिएString.indexOf
Alnitak

3
function getPosition(str, m, i) { return str.split(m, i).join(m).length; }
कॉपी

9
मैं अच्छा होता अगर आप निर्दिष्ट करते कि प्रत्येक पैरामीटर का क्या मतलब है।
हमेशा के लिए

1
@ कभी-कभी मैंने ओपी द्वारा परिभाषित फ़ंक्शन को लागू किया है
डेनिस सेगुरेट

5
यदि आप <की iघटनाएँ हैं तो यह आपको स्ट्रिंग की लंबाई देने जा रही है m। यही कारण है कि, getPosition("aaaa","a",5)देता 4है getPosition("aaaa","a",72)! मुझे लगता है कि आप उन मामलों में -1 चाहते हैं। var ret = str.split(m, i).join(m).length; return ret >= str.length ? -1 : ret;तुम भी पकड़ करने के लिए चाहते हो सकता है i <= 0के साथreturn ret >= str.length || i <= 0 ? -1 : ret;
Ruffin

70

आप बिना किसी ऐरे को बनाए भी स्ट्रिंग इंडेक्सऑफ का उपयोग कर सकते हैं।

दूसरा पैरामीटर अगले मैच की तलाश शुरू करने के लिए सूचकांक है।

function nthIndex(str, pat, n){
    var L= str.length, i= -1;
    while(n-- && i++<L){
        i= str.indexOf(pat, i);
        if (i < 0) break;
    }
    return i;
}

var s= "XYZ 123 ABC 456 ABC 789 ABC";

nthIndex(s,'ABC',3)

/*  returned value: (Number)
24
*/

लंबाई कैशिंग और स्ट्रिंग प्रोटोटाइप का विस्तार नहीं करने के कारण मुझे यह संस्करण पसंद है।
क्रिस्टोफ रूसो

8
के अनुसार jsperf इस विधि तरीका है तेजी से स्वीकार किए जाते हैं जवाब से
BOOP

वेतन वृद्धि को iकम भ्रामक बनाया जा सकता है:var i; for (i = 0; n > 0 && i !== -1; n -= 1) { i = str.indexOf(pat, /* fromIndex */ i ? (i + 1) : i); } return i;
३:११

1
मैं इसे स्वीकार किए गए उत्तर के रूप में पसंद करता हूं जब मैंने एक दूसरे उदाहरण के लिए परीक्षण किया था जो मौजूद नहीं था दूसरे उत्तर ने पहले स्ट्रिंग की लंबाई लौटा दी जहां यह -1 वापस आ गया। एक वोट और धन्यवाद।
जॉन

2
यह बेतुका है कि यह जेएस की सुविधा में निर्मित नहीं है।
सिनिस्टर बियर्ड

20

केनेबेक के उत्तर से काम करते हुए, मैंने एक प्रोटोटाइप फ़ंक्शन बनाया, जो -1 को लौटाएगा यदि 0 के बजाय nth की घटना नहीं मिली है।

String.prototype.nthIndexOf = function(pattern, n) {
    var i = -1;

    while (n-- && i++ < this.length) {
        i = this.indexOf(pattern, i);
        if (i < 0) break;
    }

    return i;
}

2
कभी भी कैमलकेस का उपयोग करें क्योंकि मूल रूप से सुविधाओं के अंतिम अनुकूलन को अनायास ही इस प्रोटोटाइप द्वारा अधिलेखित किया जा सकता है। इस मामले में मैं सभी निचले मामले और अंडरस्कोर (URL के लिए डैश) की सिफारिश करूंगा String.prototype.nth_index_of:। यहां तक ​​कि अगर आपको लगता है कि आपका नाम अद्वितीय और पागल है, तो दुनिया यह साबित करेगी कि यह पागल हो सकता है और कर देगा।
जॉन

खासतौर पर जब प्रोटोटाइप बनाने का। निश्चित रूप से, कोई भी कभी भी उस विशिष्ट विधि का उपयोग नहीं कर सकता है, हालांकि अपने आप को यह करने की अनुमति देकर कि आप एक बुरी आदत बनाते हैं। एक अलग हालांकि महत्वपूर्ण उदाहरण: हमेशा एसक्यूएल करते समय डेटा को संलग्न करें INSERTक्योंकि एकल उद्धरण हैक के खिलाफ सुरक्षा नहींmysqli_real_escape_string करता है । अधिकांश पेशेवर कोडिंग में केवल अच्छी आदतें नहीं होती हैं, हालांकि यह भी समझना कि ऐसी आदतें क्यों महत्वपूर्ण हैं। :-)
जॉन

1
स्ट्रिंग प्रोटोटाइप का विस्तार न करें।

4

क्योंकि पुनरावृत्ति हमेशा उत्तर होती है।

function getPosition(input, search, nth, curr, cnt) {
    curr = curr || 0;
    cnt = cnt || 0;
    var index = input.indexOf(search);
    if (curr === nth) {
        if (~index) {
            return cnt;
        }
        else {
            return -1;
        }
    }
    else {
        if (~index) {
            return getPosition(input.slice(index + search.length),
              search,
              nth,
              ++curr,
              cnt + index + search.length);
        }
        else {
            return -1;
        }
    }
}

1
@RenanCoelho टिल्ड ( ~) जावास्क्रिप्ट में बिटवाइज़ NOT ऑपरेटर है: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Sébastien

2

यहां मेरा समाधान है, जो nमैच होने तक स्ट्रिंग पर बस पुनरावृति करता है:

String.prototype.nthIndexOf = function(searchElement, n, fromElement) {
    n = n || 0;
    fromElement = fromElement || 0;
    while (n > 0) {
        fromElement = this.indexOf(searchElement, fromElement);
        if (fromElement < 0) {
            return -1;
        }
        --n;
        ++fromElement;
    }
    return fromElement - 1;
};

var string = "XYZ 123 ABC 456 ABC 789 ABC";
console.log(string.nthIndexOf('ABC', 2));

>> 16

2

यह विधि एक फ़ंक्शन बनाती है जो किसी सरणी में संग्रहीत nth घटनाओं के सूचकांक के लिए कॉल करती है

function nthIndexOf(search, n) { 
    var myArray = []; 
    for(var i = 0; i < myString.length; i++) { //loop thru string to check for occurrences
        if(myStr.slice(i, i + search.length) === search) { //if match found...
            myArray.push(i); //store index of each occurrence           
        }
    } 
    return myArray[n - 1]; //first occurrence stored in index 0 
}

मुझे नहीं लगता कि आपने उपरोक्त कोड में myString को परिभाषित किया है, और निश्चित नहीं है कि myStr === myString?
सेठ ईडन

1

छोटा रास्ता और मुझे लगता है कि आसान है, बिना अनावश्यक तार पैदा किए।

const findNthOccurence = (string, nth, char) => {
  let index = 0
  for (let i = 0; i < nth; i += 1) {
    if (index !== -1) index = string.indexOf(char, index + 1)
  }
  return index
}

0

का उपयोग करना indexOfऔर पुनरावृत्ति :

पहले जांच लें कि क्या nth पोजिशन पास की गई है, घटती संख्या की कुल संख्या से अधिक है। यदि पास हो जाता है, तो पुन: प्रत्येक सूचकांक के माध्यम से जाना जाता है जब तक कि एनटीटी नहीं मिलता है।

var getNthPosition = function(str, sub, n) {
    if (n > str.split(sub).length - 1) return -1;
    var recursePosition = function(n) {
        if (n === 0) return str.indexOf(sub);
        return str.indexOf(sub, recursePosition(n - 1) + 1);
    };
    return recursePosition(n);
};

0

का उपयोग करते हुए [String.indexOf][1]

var stringToMatch = "XYZ 123 ABC 456 ABC 789 ABC";

function yetAnotherGetNthOccurance(string, seek, occurance) {
    var index = 0, i = 1;

    while (index !== -1) {
        index = string.indexOf(seek, index + 1);
        if (occurance === i) {
           break;
        }
        i++;
    }
    if (index !== -1) {
        console.log('Occurance found in ' + index + ' position');
    }
    else if (index === -1 && i !== occurance) {
        console.log('Occurance not found in ' + occurance + ' position');
    }
    else {
        console.log('Occurance not found');
    }
}

yetAnotherGetNthOccurance(stringToMatch, 'ABC', 2);

// Output: Occurance found in 16 position

yetAnotherGetNthOccurance(stringToMatch, 'ABC', 20);

// Output: Occurance not found in 20 position

yetAnotherGetNthOccurance(stringToMatch, 'ZAB', 1)

// Output: Occurance not found

0
function getStringReminder(str, substr, occ) {
   let index = str.indexOf(substr);
   let preindex = '';
   let i = 1;
   while (index !== -1) {
      preIndex = index;
      if (occ == i) {
        break;
      }
      index = str.indexOf(substr, index + 1)
      i++;
   }
   return preIndex;
}
console.log(getStringReminder('bcdefgbcdbcd', 'bcd', 3));

-2

मैं StackOverflow पर एक और प्रश्न के लिए निम्नलिखित कोड के साथ खेल रहा था और सोचा कि यह यहाँ के लिए उपयुक्त हो सकता है। फ़ंक्शन PrintList2 एक regex के उपयोग की अनुमति देता है और क्रम में सभी घटनाओं को सूचीबद्ध करता है। (प्रिंटलिस्ट पहले के समाधान पर एक प्रयास था, लेकिन यह कई मामलों में विफल रहा।)

<html>
<head>
<title>Checking regex</title>
<script>
var string1 = "123xxx5yyy1234ABCxxxabc";
var search1 = /\d+/;
var search2 = /\d/;
var search3 = /abc/;
function printList(search) {
   document.writeln("<p>Searching using regex: " + search + " (printList)</p>");
   var list = string1.match(search);
   if (list == null) {
      document.writeln("<p>No matches</p>");
      return;
   }
   // document.writeln("<p>" + list.toString() + "</p>");
   // document.writeln("<p>" + typeof(list1) + "</p>");
   // document.writeln("<p>" + Array.isArray(list1) + "</p>");
   // document.writeln("<p>" + list1 + "</p>");
   var count = list.length;
   document.writeln("<ul>");
   for (i = 0; i < count; i++) {
      document.writeln("<li>" +  "  " + list[i] + "   length=" + list[i].length + 
          " first position=" + string1.indexOf(list[i]) + "</li>");
   }
   document.writeln("</ul>");
}
function printList2(search) {
   document.writeln("<p>Searching using regex: " + search + " (printList2)</p>");
   var index = 0;
   var partial = string1;
   document.writeln("<ol>");
   for (j = 0; j < 100; j++) {
       var found = partial.match(search);
       if (found == null) {
          // document.writeln("<p>not found</p>");
          break;
       }
       var size = found[0].length;
       var loc = partial.search(search);
       var actloc = loc + index;
       document.writeln("<li>" + found[0] + "  length=" + size + "  first position=" + actloc);
       // document.writeln("  " + partial + "  " + loc);
       partial = partial.substring(loc + size);
       index = index + loc + size;
       document.writeln("</li>");
   }
   document.writeln("</ol>");

}
</script>
</head>
<body>
<p>Original string is <script>document.writeln(string1);</script></p>
<script>
   printList(/\d+/g);
   printList2(/\d+/);
   printList(/\d/g);
   printList2(/\d/);
   printList(/abc/g);
   printList2(/abc/);
   printList(/ABC/gi);
   printList2(/ABC/i);
</script>
</body>
</html>

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.