1

I am trying to convert a Dart pipe to typescript, but there does not seem to be an equivalent of StringBuffer in typescript. The Dart code is shown below

.dart

@Pipe( name: 'titleCase' )
class TitleCasePipe extends PipeTransform {
  dynamic transform( String value, List args ) {
    StringBuffer buffer = new StringBuffer( );

    if ( !isNull( value ) ) {
      List<String> list = value.split( '' );

      if ( value.startsWith( new RegExp( r"^[is]{1,2}([A-Z]|[0-9])" ) ) ) {
        int start = 2;
        List<String> sublist = list.sublist( start );
        return sublist.join( '' );
      }

      for ( int i = 0; i < list.length; i++ ) {
        if ( i == 0 ) {
          buffer.write( list[i].toUpperCase( ) );
          continue;
        }

        if ( isUppercase( list[i] ) ) {
          buffer.write( ' ' );
          buffer.write( list[i] );
          continue;
        }

        buffer.write( list[i] );
      }
    }
    return buffer.toString( );
  }
}

What is the best substitution for String buffer or how best can I convert the pipe using typescript.

Thanks

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
st_clair_clarke
  • 5,453
  • 13
  • 49
  • 75

2 Answers2

1

I would use an array

@Pipe({ name: 'titleCase'})
class TitleCasePipe extends PipeTransform {
  transform(value:string, args:any[] ):any {
    buffer:string[] = [];

    if ( !isNull( value ) ) {
      list:string[] = value.split( '' );


      if ( value.match(/^[is]{1,2}([A-Z]|[0-9]).*/ ) ) {
        start:number = 2;
        sublist:string[] = list.slice( start );
        return sublist.join( '' );
      }

      for (i = 0; i < list.length; i++ ) {
        if ( i == 0 ) {
          buffer.push( list[i].toUpperCase( ) );
          continue;
        }

        if ( isUppercase( list[i] ) ) {
          buffer.push( ' ' );
          buffer.push( list[i] );
          continue;
        }

        buffer.push( list[i] );
      }
    }
    return buffer.join('');
  }
}

(caution - not tested)

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
0

Strings in TypeScript (and JavaScript) are mutable and iteratable.

var foo = "How Brown Cow";
> undefined
foo[2]
> "w"

In other languages where strings are immutable, you need a special StringBuffer or StringBuilder type to do concatenation or manipulation. With TypeScript you can do this with a simple string type.

That said, it looks like your titleCase pipe could be achieved with a simple regular expression rather than imperative code.

How to convert "camelCase" to "Camel Case"?

@Pipe('titleCase')
export class TitleCase implements PipeTransform {
  transform(value: string | null) {
    if (!value) return;

    return value
      .replace(/([A-Z])/g, ' $1')
      .replace(/^./, s => s.toUpperCase());
  }
}

It should be noted that Angular provides a titleCase pipe.

Martin
  • 15,820
  • 4
  • 47
  • 56
  • 1
    Strings in JavaScript are not mutable, that code does not mutate the variable `foo` – lpil May 03 '21 at 14:48
  • Never said `foo` was mutable. What I said are strings are mutable. In JavaScript/TypeScript you don't need a StringBuffer, StringBuilder or a special mutable type to modify strings as the Dart example shows. You can just do, `let buffer = "";, and modify that. Duplicating this string manipulation from Dart is not the best solution. Using Regexp is a much better way. – Martin May 05 '21 at 10:20
  • 1
    That is not true. Strings are not mutable in JavaScript, see this SO question for more details. https://stackoverflow.com/questions/51185/are-javascript-strings-immutable-do-i-need-a-string-builder-in-javascript What you are describing is ressigning a variable. – lpil May 06 '21 at 13:40