현을 연결하는 방법이 있습니까?


89

Javascript splice는 배열에서만 작동합니다. 문자열에 대한 유사한 방법이 있습니까? 아니면 나만의 사용자 지정 함수를 만들어야합니까?

substr()substring()방법은 추출 된 문자열을 반환하고 원래 문자열을 수정하지 않습니다. 내가 원하는 것은 내 문자열에서 일부를 제거하고 변경 사항을 원래 문자열에 적용하는 것입니다. 또한 replace()인덱스에서 시작하여 다른 인덱스에서 끝나는 부분을 제거하고 싶기 때문에 메서드로 수행 할 수 있는 것과 똑같이이 메서드 가 작동하지 않습니다 splice(). 내 문자열을 배열로 변환하려고 시도했지만 이것은 깔끔한 방법이 아닙니다.


str.split: 당신이 찾고있는 기능 수 있습니다 google.com/#q=javascript+string+split
앤더슨 녹색

1
뭐가 잘못 str = str.slice()됐나요?
elclanrs

1
XY 문제인 것 같습니다. 정확히 무엇을하려고합니까? 문자열은 배열 및 객체와 달리 참조로 전달되지 않으므로 문자열을 변경하지 않고 새 항목을 만들거나 새 항목을 이전 항목에 다시 할당합니다.
elclanrs dec


6
return string.slice(0, startToSplice) + string.slice(endToSplice);, 아니?
raina77ow dec

답변:


89

다음과 같이 문자열을 두 번 슬라이스하는 것이 더 빠릅니다.

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);
}

다음과 같이 분할 후 조인 (Kumar Harsh의 방법)을 사용하는 것보다

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*/};불변이라고 말했듯이 문자열 조작의 표준이 될 것입니다.
Mr. Polywhirl 2014

spliceSlice와 spliceSplit은 Array.prototype.splice가 음수 인덱스를 받아들이 기 때문에 기능적으로 동일하지 않습니다 : jsfiddle.net/sykteho6/5 .
Martijn

1
@Mzialla 감사합니다. 코드를 추가했습니다.
Louis

split ( ""). splice (...). join ( "")과 달리 사람이 처리하는 데 더 오래 걸리는 코드는 말할 것도없고 임시 변수를 만들고 off-by-one 오류를위한 장소를 도입하는 것은 트레이드 오프입니다. 고려할 가치가 있습니다. 속도 문제는 문제 일 경우에만 문제가됩니다.
Ben Fletcher

16

편집하다

이것은 물론 문자열을 "스플 라이스"하는 가장 좋은 방법은 아닙니다. 구현 방법에 대한 예제로 이것을 제공했습니다. 이는 split (), splice () 및 join ()에서 결함이 있고 매우 분명합니다. 훨씬 더 나은 구현을 위해 Louis의 방법을 참조하십시오 .


아니요,과 같은 것은 String.splice없지만 다음을 시도해 볼 수 있습니다.

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

splice배열에서와 같은 기능 이 없다는 것을 알고 있으므로 문자열을 배열로 변환해야합니다. 곤경...


제 경우에는 동적 문자열에서 작업하므로 문자 값이 아닌 인덱스를 지정해야합니다.
ProllyGeek

네, 안타깝게도 맞습니다. 그러나 당신은 String.prototype.indexOf를 사용하여 문자의 인덱스를 얻을 수 있습니다"asdsd".indexOf('s');
kumarharsh

3
str.split을 사용하는 대신 다음과 같이 ES6 스프레드 구문을 사용할 수 있습니다.[...str]
robbie

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'); 빈 호출의 카레를 제거하기 위해 인수를 duckType 할 수도 있습니다. 심지어 메서드 자체를 캡슐화 할 수도 있습니다. 이 물건이 필요하면 명령 패턴 을 살펴 보는 것이 좋습니다. 여기서 뱉어 내세요.
Cody

3

Kumar / Cody와 Louis 방법에 대한 더 간단한 대안을 제공하고 싶습니다. 내가 실행 한 모든 테스트에서 Louis 방법만큼 빠르게 수행됩니다 (벤치 마크는 바이올린 테스트 참조).

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 다른 제안과 달리 적어도`+ insertString + startIndex <0` 대신`+ (insertString || "") +`를 수행해야 합니다. 하지만 사용의 훌륭한 예
YakovL

3

elclanrs 및 raina77ow의 의견에서만 해결 된 많은 혼란이있는 것 같으므로 명확한 답변을 게시하겠습니다.

설명

" string.splice"에서 다음과 같이 예상 할 수 있습니다.

  • 최대 3 개의 인수 허용 : 시작 위치, 길이 및 (선택적으로) 삽입 (문자열)
  • 잘라낸 부분을 반환
  • 원래 문자열을 수정합니다.

문제는 문자열이 변경 불가능하기 때문에 3d 요구 사항을 충족 할 수 없다는 것입니다 (관련 : 1 , 2 ). 여기서 가장 헌신적 인 주석을 찾았습니다 .

JavaScript에서 문자열은 객체가 아닌 원시 값 유형입니다 ( spec ). 사실, ES5의, 그들은 나란히 5 값 유형 중 하나를있어 null, undefined, numberboolean. 문자열에 의해 할당 된 하지 참조 등으로 전달된다. 따라서 문자열은 불변 일뿐만 아니라 입니다. 문자열 "hello"을 변경 "world"하는 것은 지금부터 숫자 3이 숫자 4라고 결정하는 것과 같습니다.

따라서이를 고려하여 " string.splice"항목 만 다음과 같이 예상 할 수 있습니다 .

  • 최대 2 개의 인수 허용 : 시작 위치, 길이 (문자열이 변경되지 않았으므로 삽입이 의미가 없음)
  • 잘라낸 부분을 반환

그것이 무엇을 하는가 substr; 또는,

  • 최대 3 개의 인수 허용 : 시작 위치, 길이 및 (선택적으로) 삽입 (문자열)
  • 수정 된 문자열을 반환합니다 (절단 부분없이 삽입).

다음 섹션의 주제입니다.

솔루션

최적화에 관심이 있다면 Mike의 구현을 사용해야 할 것입니다.

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;

성능에 신경 쓰지 않는다면 Kumar의 제안을보다 간단하게 적용 할 수 있습니다.

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

공연

연주의 차이는 현의 길이에 따라 크게 증가합니다. jsperf 길이가 10 인 문자열의 경우 후자의 솔루션 (분할 및 결합)이 이전 솔루션 (슬라이스 사용)보다 두 배 느리고 100 자 문자열의 경우 x5이고 1000 자 문자열의 경우 x50이며 Ops /에서 초 그것은 :

                      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

10 글자에서 100 글자로 이동할 때 첫 번째와 두 번째 인수를 변경했습니다 (여전히 100 글자 테스트가 10 글자 테스트보다 빠르다는 사실에 놀랐습니다).


2

단순히 문자열에 substr 을 사용하십시오.

전의.

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

결과 = 안녕하세요!


1

따라서 문자열 프로토 타입에 splice 메서드를 추가하는 것은 사양에 투명하게 작동하지 않습니다.

하나를 확장 해 보겠습니다.

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 개의 args 그룹이 스플 라이스 스타일로 "삽입"합니다.
  • 3 개 이상의 args 그룹이있는 경우 특히 각 컷의 끝이 다음 시작이됩니다.
    • '0123456789'.splice (4,1,'fourth ', 8,1,'eighth '); // '0123fourth567eighth9'반환
  • 각 그룹의 마지막 인수를 삭제하거나 0으로 만들 수 있습니다 ( "삽입 할 항목 없음"으로 처리됨).
    • '0123456789'.splice (-4,2); // '0123459'반환
  • 마지막 그룹에서 첫 번째 인수를 제외한 모든 항목을 삭제할 수 있습니다 ( "첫 번째 인수 위치 이후 모두 잘라 내기"로 처리됨).
    • '0123456789'.splice (0,2, null, 3,1, null, 5,2,'/ ', 8); // '24/7'반환
  • 여러 번 통과하면 왼쪽에서 오른쪽으로 순서를 직접 확인해야합니다!
  • 그리고 원하지 않는 경우 다음과 같이 사용해서는 안됩니다.
    • '0123456789'.splice (4, -3,'what? '); // "0123what? 123456789"반환

0

프로토 타입 함수 로서의 방법 Louis의 대답 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이거나 다른 잘못된 값일 때 Louis의 spliceSlice 메서드가 실패합니다. 다음은 수정 사항입니다.

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.