तार के लिए एक ब्याह विधि है?


87

जावास्क्रिप्ट spliceकेवल सरणियों के साथ काम करता है। क्या तार के समान विधि है? या मुझे अपना स्वयं का कस्टम फ़ंक्शन बनाना चाहिए?

substr(), और substring()तरीकों को निकाले स्ट्रिंग वापस आ जाएगी और मूल स्ट्रिंग को संशोधित नहीं। जो मैं करना चाहता हूं, वह मेरी स्ट्रिंग से कुछ हिस्सा हटा दें और मूल स्ट्रिंग में परिवर्तन लागू करें। इसके अलावा, विधि replace()मेरे मामले में काम नहीं करेगी क्योंकि मैं एक इंडेक्स से शुरू होने वाले भागों को निकालना चाहता हूं और कुछ अन्य इंडेक्स पर समाप्त होता है, ठीक उसी तरह जैसे मैं splice()विधि के साथ क्या कर सकता हूं । मैंने अपने स्ट्रिंग को एक सरणी में बदलने की कोशिश की, लेकिन यह एक साफ तरीका नहीं है।


str.splitवह कार्य हो सकता है जिसे आप देख रहे हैं: google.com/#q=javascript+string+split
— एंडरसन ग्रीन

1
इसमें गलत क्या है str = str.slice()?
— एलक्लेनर्स

1
एक XY समस्या की तरह लग रहा है, आप वास्तव में क्या करने की कोशिश कर रहे हैं? स्ट्रिंग और ऑब्जेक्ट्स के विपरीत स्ट्रिंग्स को संदर्भ द्वारा पारित नहीं किया जाता है, इसलिए आप स्ट्रिंग्स को म्यूट नहीं करते हैं, आप नए बनाते हैं या पुराने को नया असाइन करते हैं।
— एलक्लेन्स 18


6
return string.slice(0, startToSplice) + string.slice(endToSplice);, नहीं?
— बारिश।।

जवाबों:


88

यह स्ट्रिंग को दो बार काटने के लिए तेज़ है, जैसे:

function spliceSlice(str, index, count, add) {
  // We cannot pass negative indexes directly to the 2nd slicing operation.
  if (index < 0) {
    index = str.length + index;
    if (index < 0) {
      index = 0;
    }
  }

  return str.slice(0, index) + (add || "") + str.slice(index + count);
}

एक स्प्लिट (कुमार हर्ष की विधि) के बाद विभाजन का उपयोग करने से, इस तरह से:

function spliceSplit(str, index, count, add) {
  var ar = str.split('');
  ar.splice(index, count, add);
  return ar.join('');
}

यहाँ एक jsperf है, जो दो और कुछ अन्य तरीकों की तुलना करता है। (jsperf अब कुछ महीनों के लिए डाउन हो गया है। कृपया टिप्पणियों में विकल्प सुझाएं।)

हालाँकि, उपर्युक्त कोड कार्य करता है जो सामान्य कार्यक्षमता को पुन: उत्पन्न करता है splice, पूछने वाले द्वारा प्रस्तुत मामले के लिए कोड का अनुकूलन (अर्थात, संशोधित स्ट्रिंग में कुछ भी नहीं जोड़ना) विभिन्न तरीकों के सापेक्ष प्रदर्शन को नहीं बदलता है।


3
आप इसे विश्व स्तर पर जोड़ सकते हैं: String.prototype.splice = function (index, count, add) { return this.slice(0, index) + (add || "") + this.slice(index + count); } बस ध्यान रखें कि यह ऐरे स्प्लिस विधि के समान काम नहीं करता है क्योंकि तार अपरिवर्तनीय होते हैं (आप इन्हें एक बार बनाए जाने के बाद संशोधित नहीं कर सकते हैं)। इसलिए उपयोग इस तरह होगा:var s="ss"; s = s.splice(0,1,"t");
— विलियम नेली

@WilliamNeely: var StringUtils={'StringSplice':/*func def*/};स्ट्रिंग हेरफेर के लिए मानक होगा जैसा कि आपने कहा है कि यह अपरिवर्तनीय है।
— श्री पॉलीविरल

SpliceSlice और spliceSplit कार्यात्मक रूप से Array.prototype.splice नकारात्मक सूचकांकों को स्वीकार करने के कारण समान नहीं हैं: jsfiddle.net/sykteho6/5 ।
— मार्टिज़न

1
@ मजील्ला धन्यवाद, मैंने इसकी देखभाल के लिए कोड जोड़ा है।
— लुई

अस्थायी संस्करण बनाना और ऑफ-बाय-वन त्रुटियों के लिए स्थानों को प्रस्तुत करना, कोड का उल्लेख नहीं करना है जो मनुष्यों को विभाजित करने के लिए प्रक्रिया करने में अधिक समय लेता है ("")। ब्याह (...)। ज्वाइन ("") एक व्यापार है। विचार योग्य है। यदि यह कोई समस्या है तो गति समस्या केवल एक समस्या है।
— बेन फ्लेचर

15

संपादित करें

यह निश्चित रूप से एक स्ट्रिंग को "विभाजित" करने का सबसे अच्छा तरीका नहीं है, मैंने इसे एक उदाहरण के रूप में दिया था कि कार्यान्वयन कैसे होगा, जो त्रुटिपूर्ण है और एक विभाजन (), ब्याह () और ज्वाइन () से बहुत स्पष्ट है। बेहतर कार्यान्वयन के लिए, लुईस की विधि देखें ।


नहीं, ऐसी कोई बात नहीं है String.splice, लेकिन आप यह कोशिश कर सकते हैं:

newStr = str.split(''); // or newStr = [...str];
newStr.splice(2,5);
newStr = newStr.join('');

मुझे लगता है कि spliceअर्र्स में कोई फ़ंक्शन नहीं है , इसलिए आपको स्ट्रिंग को एक सरणी में बदलना होगा। बदकिस्मत...


मेरे मामले में मैं एक गतिशील स्ट्रिंग पर काम कर रहा हूं, इसलिए मुझे सूचकांक निर्दिष्ट करने की आवश्यकता है और चरित्र मूल्य नहीं।
— ProllyGeek

हाँ, यह दुर्भाग्य से सही है। लेकिन आप String.prototype.indexOf का उपयोग करके किसी वर्ण का सूचकांक प्राप्त कर सकते हैं"asdsd".indexOf('s');
— कुमारहर्ष

3
Str.split का उपयोग करने के बजाय, आप ES6 स्प्रेड सिंटैक्स का उपयोग कर सकते हैं जैसे:[...str]
— रॉबी

5

यहाँ एक छोटी सी करी है जो बेहतर पठनीयता (IMHO) उधार देती है:

दूसरे फ़ंक्शन का हस्ताक्षर Array.prototype.spliceविधि के समान है ।

function mutate(s) {
    return function splice() {
        var a = s.split('');
        Array.prototype.splice.apply(a, arguments);
        return a.join('');
    };
}

mutate('101')(1, 1, '1');

मुझे पता है कि पहले से ही एक स्वीकृत उत्तर है, लेकिन आशा है कि यह उपयोगी है।


1
Np। आप इसे एक वैकल्पिक 'method'पैरामीटर की अनुमति देने के लिए भी सार कर सकते हैं, एक वैकल्पिक पैरामीटर ताकि आप पास कर सकें Array.prototype[method]और पूरी तरह से सरणियों की तरह तार का इलाज कर सकें । इसके अलावा, इस अकेले के साथ, आप वास्तविक प्रक्रिया को किसी अन्य फ़ंक्शन में सार कर सकते हैं - और अगर कोई स्ट्रिंग नहीं है, तो एक फ़ंक्शन वापस करें जो स्ट्रिंग ले जाएगा और करी को उलट देगा mutate()(1, 1, '1')('101'):; तुम भी खाली आह्वान की करी से छुटकारा पाने के लिए तर्कों को तोड़-मरोड़ सकते थे - यहां तक ​​कि एक विधि को भी, अपने आप को संलग्न कर सकते थे। यदि आपको इस सामान की आवश्यकता है, तो आप कमांड पैटर्न में देखना चाह सकते हैं । बस यहां थूकना है।
— कोडी

3

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

String.prototype.splice = function(startIndex,length,insertString){
    return this.substring(0,startIndex) + insertString + this.substring(startIndex + length);
};

आप इसे इस तरह से उपयोग कर सकते हैं:

var creditCardNumber = "5500000000000004";
var cardSuffix = creditCardNumber.splice(0,12,'****');
console.log(cardSuffix);  // output: ****0004

परीक्षा परिणाम देखें: https://jsfiddle.net/0quz9q9m/5/


आपको कम से कम `+ (इन्सर्ट `स्ट्रिंग ||" ") करना चाहिए , otherwise the third argument is not optional. This implementation also doesn't take care of । उपयोग का शानदार उदाहरण, हालांकि
— याकॉव

3

ऐसा लगता है कि बहुत सारे भ्रम हैं जो केवल एल्क्लानेर और रेनॉ77 द्वारा टिप्पणियों में संबोधित किए गए थे, इसलिए मुझे एक स्पष्ट जवाब देना चाहिए।

स्पष्टीकरण

" string.splice" से कोई यह उम्मीद कर सकता है कि यह सरणियों के लिए पसंद है:

  • 3 तर्क तक स्वीकार करते हैं: स्थिति, लंबाई और (वैकल्पिक रूप से) सम्मिलन (स्ट्रिंग) शुरू करें
  • कट आउट भाग लौटाता है
  • मूल स्ट्रिंग को संशोधित करता है

समस्या यह है, 3 डी आवश्यकता को पूरा नहीं किया जा सकता है क्योंकि तार अपरिवर्तनीय हैं (संबंधित: 1 , 2 ), मैंने यहां सबसे समर्पित टिप्पणी पाई है :

जावास्क्रिप्ट में तार आदिम मूल्य प्रकार हैं और न कि ऑब्जेक्ट ( युक्ति )। वास्तव में, ES5 के रूप में, वे केवल 5 मान प्रकारों में nullसे एक हैं undefined, numberऔर boolean। स्ट्रिंग्स को मूल्य द्वारा निर्दिष्ट किया जाता है और संदर्भ द्वारा नहीं और इस तरह से पारित किया जाता है। इस प्रकार, तार सिर्फ अपरिवर्तनीय नहीं हैं, वे एक मूल्य हैं । स्ट्रिंग "hello"को बदलना यह "world"निर्णय लेने जैसा है कि अब से 3 नंबर 4 है ... इसका कोई मतलब नहीं है।

तो, उस खाते के साथ, string.spliceकेवल " " बात की उम्मीद कर सकते हैं :

  • 2 तर्कों को स्वीकार करता है: स्थिति शुरू, लंबाई (प्रविष्टि कोई मतलब नहीं है क्योंकि स्ट्रिंग नहीं बदली गई है)
  • कट आउट भाग लौटाता है

जो substrकरता है; या, वैकल्पिक रूप से,

  • 3 तर्क तक स्वीकार करते हैं: स्थिति, लंबाई और (वैकल्पिक रूप से) सम्मिलन (स्ट्रिंग) शुरू करें
  • संशोधित स्ट्रिंग लौटाता है (कट भाग के बिना और सम्मिलन के साथ)

जो अगले भाग का विषय है।

समाधान

यदि आप अनुकूलन के बारे में परवाह करते हैं, तो आपको संभवतः माइक के कार्यान्वयन का उपयोग करना चाहिए:

String.prototype.splice = function(index, count, add) {
    if (index < 0) {
        index += this.length;
        if (index < 0)
            index = 0;
    }
    return this.slice(0, index) + (add || "") + this.slice(index + count);
}

आउट-ऑफ-बाउंड्री इंडेक्स का इलाज करना अलग हो सकता है, हालांकि। अपनी आवश्यकताओं के आधार पर, आप चाहें:

    if (index < 0) {
        index += this.length;
        if (index < 0)
            index = 0;
    }
    if (index >= this.length) {
        index -= this.length;
        if (index >= this.length)
            index = this.length - 1;
    }

या और भी

    index = index % this.length;
    if (index < 0)
        index = this.length + index;

यदि आप प्रदर्शन के बारे में परवाह नहीं करते हैं, तो आप कुमार के सुझाव को अनुकूलित करना चाह सकते हैं जो कि अधिक सीधा है:

String.prototype.splice = function(index, count, add) {
    var chars = this.split('');
    chars.splice(index, count, add);
    return chars.join('');
}

प्रदर्शन

स्ट्रिंग की लंबाई के साथ प्रदर्शन में अंतर काफी बढ़ जाता है। jsperf दिखाता है , कि 10 की लंबाई वाले स्ट्रिंग्स के लिए बाद वाला सॉल्यूशन (बंटवारा और जुड़ना) पूर्व समाधान (स्लाइस का उपयोग करके) की तुलना में दोगुना है, 100 अक्षर के स्ट्रिंग्स के लिए यह x5 है और 1000 अक्षरों के स्ट्रिंग्स के लिए यह O50 / में x50 है यह सुरक्षित है:

                      10 letters   100 letters   1000 letters
slice implementation    1.25 M       2.00 M         1.91 M
split implementation    0.63 M       0.22 M         0.04 M

ध्यान दें कि मैंने १० अक्षरों से १०० अक्षरों की ओर बढ़ने पर पहली और २ डी बहस बदली है (फिर भी मुझे आश्चर्य है कि १०० अक्षरों की परीक्षा १० अक्षरों की तुलना में तेजी से चलती है)।


2

बस स्ट्रिंग के लिए रूट का उपयोग करें

पूर्व।

var str = "Hello world!";
var res = str.substr(1, str.length);

परिणाम = एलो दुनिया!


1

तो, जो कुछ भी एक String प्रोटोटाइप केंट काम करने के लिए पारदर्शी के लिए ब्याह विधि जोड़ने ...

चलो कुछ इसे बढ़ाएँ:

String.prototype.splice = function(...a){
    for(var r = '', p = 0, i = 1; i < a.length; i+=3)
        r+= this.slice(p, p=a[i-1]) + (a[i+1]||'') + this.slice(p+a[i], p=a[i+2]||this.length);
    return r;
}
  • हर 3 आलीशान समूह "बंटवारे" को ब्याह शैली में करता है।
  • विशेष यदि अधिक है तो एक 3 आर्ग्स समूह है, प्रत्येक कट का अंत अगले की शुरुआत होगी।
    • '0123456789'.splice (4,1,' चौथे ', 8,1,' आठवें '); // वापसी '0123fourth567eIII9'
  • आप प्रत्येक समूह में अंतिम arg को ड्रॉप या शून्य कर सकते हैं (जिसे "डालने के लिए कुछ नहीं" के रूप में माना जाता है)
    • '0123456789'.splice (-4,2); // वापसी '0123459'
  • आप अंतिम समूह में 1 arg को छोड़कर सभी को छोड़ सकते हैं (जिसे "1 arg स्थिति के बाद सभी को काटें" माना जाता है)
    • '0123456789'.splice (0,2, अशक्त, 3,1, अशक्त, 5,2,' / ', 8); // वापसी '24 / 7 '
  • यदि आप कई पास करते हैं, तो आप अपने द्वारा बाएं-से-दाएं क्रम के पदों की जांच अवश्य करें!
  • और यदि आप नहीं चाहते हैं कि आप इसे इस तरह उपयोग न करें:
    • '0123456789'.splice (4, -3,' क्या?); // वापसी "0123what? 123456789"

0

एक प्रोटोटाइप फ़ंक्शन के रूप में लुइस के जवाब की विधि String:

String.prototype.splice = function(index, count, add) {
  if (index < 0) {
    index = this.length + index;
    if (index < 0) {
      index = 0;
    }
  }
  return this.slice(0, index) + (add || "") + this.slice(index + count);
}

उदाहरण:

 > "Held!".splice(3,0,"lo Worl")
 < "Hello World!"

0

जब मान 0 या अन्य गलत मूल्यों को जोड़ते हैं, तो लुइस की स्प्लिस्लिस विधि विफल हो जाती है, यहाँ एक फिक्स है:

function spliceSlice(str, index, count, add) {
  if (index < 0) {
    index = str.length + index;
    if (index < 0) {
      index = 0;
    }
  }
  const hasAdd = typeof add !== 'undefined';
  return str.slice(0, index) + (hasAdd ? add : '') + str.slice(index + count);
}

0

मैंने इस कोड का उपयोग करके अपनी समस्या को हल किया, लापता ब्याह के लिए कुछ हद तक प्रतिस्थापन है।

let str = "I need to remove a character from this";
let pos = str.indexOf("character")

if(pos>-1){
  let result = str.slice(0, pos-2) + str.slice(pos, str.length);
  console.log(result) //I need to remove character from this 
}

मुझे एक निश्चित शब्द के पहले / बाद में एक चरित्र को हटाने की आवश्यकता है, आपके द्वारा स्थिति को प्राप्त करने के बाद स्ट्रिंग को दो में विभाजित किया जाता है और फिर लचीले ढंग से हटाए गए अक्षरों के साथ एक ऑफसेट का उपयोग करके पुनः स्थापित pos

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