Camel case and snake case: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added XPL0 example.)
Line 291: Line 291:
c://my-docs/happy_Flag-Day/12.doc -> c://myDocs/happyFlagDay/12.doc
c://my-docs/happy_Flag-Day/12.doc -> c://myDocs/happyFlagDay/12.doc
spaces -> spaces
spaces -> spaces
</pre>

=={{header|XPL0}}==
<lang XPL0>string 0; \use zero-terminated strings
char Out(100); \output string (made global for safety)

func Trim(Str); \Trim leading and trailing spaces from string
char Str;
int I;
[while Str(0) = $20 do Str:= Str+1; \skip leading spaces
I:= 0; \skip to end of string (+1)
while Str(I) # 0 do I:= I+1;
while I>0 & Str(I-1)=$20 do I:= I-1; \skip back to first non-space
Str(I):= 0; \chop off any trailing spaces
return Str;
];

func ToSnake(In); \Convert string to snake_case
char In;
int I, J, C, UL;
[I:= 0; J:= 0; UL:= true; \suppress leading & redundant underlines
repeat C:= In(I); I:= I+1; \get character from input string
if C>=^A & C<=^Z then \convert uppercase to "_" + lowercase
[if not UL then [Out(J):= ^_; J:= J+1];
Out(J):= C+$20; J:= J+1;
UL:= false;
]
else if C=$20 or C=^- then \convert to underlines
[if not UL then [Out(J):= ^_; J:= J+1; UL:= true]
]
else [Out(J):= C; J:= J+1; UL:= C=^_];
until C = 0;
return Out;
];

func ToCamel(In); \Convert string to camelCase
char In;
int I, J, C;
[I:= 0; J:= 0;
repeat C:= In(I); I:= I+1;
if C=^_ or C=^- or C=$20 then
[C:= In(I); I:= I+1;
if C>=^a & C<=^z then C:= C-$20;
Out(J):= C; J:= J+1;
]
else [Out(J):= C; J:= J+1];
until C = 0;
return Out;
];

int Strings, I;
[Strings:= [
"snakeCase", "snake_case", "variable_10_case", "variable10Case", "\u025brgo rE tHis",
"hurry-up-joe!", "c://my-docs/happy_Flag-Day/12.doc", " spaces "];
Text(0, "To snake case:^M^J");
for I:= 0 to 7 do
[Text(0, Strings(I));
Text(0, " -> ");
Text(0, ToSnake(Trim(Strings(I))));
CrLf(0);
];
Text(0, "To camel case:^M^J");
for I:= 0 to 7 do
[Text(0, Strings(I));
Text(0, " -> ");
Text(0, ToCamel(Trim(Strings(I))));
CrLf(0);
];
]</lang>

{{out}}
<pre>
To snake case:
snakeCase -> snake_case
snake_case -> snake_case
variable_10_case -> variable_10_case
variable10Case -> variable10_case
\u025brgo rE tHis -> \u025brgo_r_e_t_his
hurry-up-joe! -> hurry_up_joe!
c://my-docs/happy_Flag-Day/12.doc -> c://my_docs/happy_flag_day/12.doc
spaces -> spaces
To camel case:
snakeCase -> snakeCase
snake_case -> snakeCase
variable_10_case -> variable10Case
variable10Case -> variable10Case
\u025brgo rE tHis -> \u025brgoRETHis
hurry-up-joe! -> hurryUpJoe!
c://my-docs/happy_Flag-Day/12.doc -> c://myDocs/happyFlagDay/12.doc
spaces -> spaces
</pre>
</pre>

Revision as of 20:16, 26 November 2021

Camel case and snake case is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Two common conventions for naming of computer program variables are Snake Case and Camel Case.

Snake case variables are generally all lower case, with an underscore between words in the variable, as in snake_case_variable'. Camel case variables are generally lower case first (except in some Pascal conventions or with class names in many other languages), with captalization of the initial letter of the words within the variable, as in 'camelCaseVariable'.

Leading underscores are not used in such variables except as part of a different naming convention, usually for special internal or system variables. White space is not permitted as part of camel case or snake case variable names.

Task
  • Write two functions, one to change snake case to camel case and one to change camel case to snake case. If possible, generalize the function enough to apply to strings containing spaces between words or a `-` dash between words, assuming that in those cases a space or hyphen is a also a separator character, like `_`, for the purpose of creating a new variable name. Leading or trailing whitespace may be ignored.
  • Show the results on changing to both snake case and camel case for each of the following strings:

<lang java> "snakeCase", "snake_case", "variable_10_case", "variable10Case", "ɛrgo rE tHis", "hurry-up-joe!", "c://my-docs/happy_Flag-Day/12.doc", " spaces " </lang>

Related tasks


Perl

<lang perl>#!/usr/bin/perl

use strict; # https://rosettacode.org/wiki/Camel_case_and_snake_case use warnings;

my @words = (

 "snakeCase", "snake_case", "variable_10_case", "variable10Case", "#rgo rE tHis",
 "hurry-up-joe!", "c://my-docs/happy_Flag-Day/12.doc", "  spaces  "
  );

sub tosnake

 {
 shift =~ s/^ +| +$//gr =~ s/[A-Z]/_\l$&/gr =~ tr/ -/_/r =~ s/__+/_/gr;
 }

sub tocamel

 {
 shift =~ s/^ +| +$//gr =~ s/[ _-]([a-z0-9])/\u$1/gir;
 }

print "to snake case\n\n"; for my $word ( @words )

 {
 printf "%35s -> %s\n", $word, tosnake($word);
 }

print "\nto camel case\n\n"; for my $word ( @words )

 {
 printf "%35s -> %s\n", $word, tocamel($word);
 }</lang>
Output:
to snake case

                          snakeCase -> snake_case
                         snake_case -> snake_case
                   variable_10_case -> variable_10_case
                     variable10Case -> variable10_case
                       #rgo rE tHis -> #rgo_r_e_t_his
                      hurry-up-joe! -> hurry_up_joe!
  c://my-docs/happy_Flag-Day/12.doc -> c://my_docs/happy_flag_day/12.doc
                           spaces   -> spaces

to camel case

                          snakeCase -> snakeCase
                         snake_case -> snakeCase
                   variable_10_case -> variable10Case
                     variable10Case -> variable10Case
                       #rgo rE tHis -> #rgoRETHis
                      hurry-up-joe! -> hurryUpJoe!
  c://my-docs/happy_Flag-Day/12.doc -> c://myDocs/happyFlagDay/12.doc
                           spaces   -> spaces

Phix

with javascript_semantics
function to_snake_case(string s)
    string snake = substitute(trim(s)," ","_")
    for i=length(snake) to 1 by -1 do
        if isupper(snake[i]) then
            snake[i..i] = '_'&lower(snake[i])
        end if
    end for
    return snake
end function

function toCamelCase(string s)
    string camel = substitute_all(trim(s),"- ","__")
    for i=length(camel)-1 to 1 by -1 do
        if camel[i]='_' then
            camel[i..i+1] = upper(camel[i+1..i+1])
        end if
    end for
    return camel
end function
 
constant tests = {"snakeCase", "snake_case", "variable_10_case", "variable10Case", "ergo rE tHis",
                  "hurry-up-joe!", "c://my-docs/happy_Flag-Day/12.doc", "  spaces  "}
procedure test(string title, integer fn)
    printf(1,title)
    for i=1 to length(tests) do
        printf(1,"%33s ===> %s\n", {tests[i], fn(tests[i])})
    end for
end procedure
test("                          === to_snake_case ===\n",to_snake_case)
test("\n                          === toCamelCase ===\n",toCamelCase)
Output:
                          === to_snake_case ===
                        snakeCase ===> snake_case
                       snake_case ===> snake_case
                 variable_10_case ===> variable_10_case
                   variable10Case ===> variable10_case
                     ergo rE tHis ===> ergo_r_e_t_his
                    hurry-up-joe! ===> hurry-up-joe!
c://my-docs/happy_Flag-Day/12.doc ===> c://my-docs/happy__flag-_day/12.doc
                         spaces   ===> spaces

                          === toCamelCase ===
                        snakeCase ===> snakeCase
                       snake_case ===> snakeCase
                 variable_10_case ===> variable10Case
                   variable10Case ===> variable10Case
                     ergo rE tHis ===> ergoRETHis
                    hurry-up-joe! ===> hurryUpJoe!
c://my-docs/happy_Flag-Day/12.doc ===> c://myDocs/happyFlagDay/12.doc
                         spaces   ===> spaces

Raku

The specs are a little vague, but taking a wild stab at it... (May be completely wrong but without any examples of expected output it is hard to judge. This is what I would expect at least...)

<lang perl6>my @tests = qww<

 snakeCase  snake_case  variable_10_case  variable10Case  "ɛrgo rE tHis"
 hurry-up-joe!  c://my-docs/happy_Flag-Day/12.doc  "  spaces  "

>;


sub to_snake_case (Str $snake_case_string is copy) {

   $snake_case_string.=trim;
   return $snake_case_string if $snake_case_string.contains: / \s | '/' /;
   $snake_case_string.=subst: / <after <:Ll>> (<:Lu>|<:digit>+) /, {'_' ~ $0.lc}, :g;
   $snake_case_string.=subst: / <after <:digit>> (<:Lu>) /, {'_' ~ $0.lc}, :g;

}

sub toCamelCase (Str $CamelCaseString is copy) {

   $CamelCaseString.=trim;
   return $CamelCaseString if $CamelCaseString.contains: / \s | '/' /;
   $CamelCaseString.=subst: / ('_') (\w) /, {$1.uc}, :g;

}

sub to-kebab-case (Str $kebab-case-string is copy) {

   $kebab-case-string.=trim;
   return $kebab-case-string if $kebab-case-string.contains: / \s | '/' /;
   $kebab-case-string.=subst: / ('_') (\w) /, {'-' ~ $1.lc}, :g;
   $kebab-case-string.=subst: / <after <:Ll>> (<:Lu>|<:digit>+) /, {'-' ~ $0.lc}, :g;
   $kebab-case-string.=subst: / <after <:digit>> (<:Lu>) /, {'-' ~ $0.lc}, :g;

}

say "{' ' x 30}to_snake_case"; printf "%33s ==> %s\n", $_, .&to_snake_case for @tests; say "\n{' ' x 30}toCamelCase"; printf "%33s ==> %s\n", $_, .&toCamelCase for @tests; say "\n{' ' x 30}to-kabab-case"; printf "%33s ==> %s\n", $_, .&to-kebab-case for @tests;</lang>

Output:
                              to_snake_case
                        snakeCase ==> snake_case
                       snake_case ==> snake_case
                 variable_10_case ==> variable_10_case
                   variable10Case ==> variable_10_case
                     ɛrgo rE tHis ==> ɛrgo rE tHis
                    hurry-up-joe! ==> hurry-up-joe!
c://my-docs/happy_Flag-Day/12.doc ==> c://my-docs/happy_Flag-Day/12.doc
                         spaces   ==> spaces

                              toCamelCase
                        snakeCase ==> snakeCase
                       snake_case ==> snakeCase
                 variable_10_case ==> variable10Case
                   variable10Case ==> variable10Case
                     ɛrgo rE tHis ==> ɛrgo rE tHis
                    hurry-up-joe! ==> hurry-up-joe!
c://my-docs/happy_Flag-Day/12.doc ==> c://my-docs/happy_Flag-Day/12.doc
                         spaces   ==> spaces

                              to-kabab-case
                        snakeCase ==> snake-case
                       snake_case ==> snake-case
                 variable_10_case ==> variable-10-case
                   variable10Case ==> variable-10-case
                     ɛrgo rE tHis ==> ɛrgo rE tHis
                    hurry-up-joe! ==> hurry-up-joe!
c://my-docs/happy_Flag-Day/12.doc ==> c://my-docs/happy_Flag-Day/12.doc
                         spaces   ==> spaces

Wren

Library: Wren-str
Library: Wren-fmt

Well, I'm not entirely sure what I'm doing here as a result of space and hyphen being treated as equivalent to underscore but, in the case of the 'to snake' conversion:

1. I've retained any hyphens in the result string but replaced spaces with underscores as it says that white space is not permitted as part of the variable name.

2. I've assumed that an underscore should not be added if the previous character was already a separator. <lang ecmascript>import "./str" for Char import "/fmt" for Fmt

var toCamel = Fn.new { |snake|

   snake = snake.trim()
   var camel = ""
   var underscore = false
   for (c in snake) {
       if ("_- ".contains(c)) {
           underscore = true
       } else if (underscore) {
           camel = camel + Char.upper(c)
           underscore = false
       } else {
           camel = camel + c
       }
   }
   return camel

}

var toSnake = Fn.new { |camel|

   camel = camel.trim().replace(" ", "_") // we don't want any spaces in the result
   var snake = ""
   var first = true
   for (c in camel) {
       if (first) {
           snake = snake + c
           first = false
       } else if (!first && Char.isUpper(c)) {
           if (snake[-1] == "_" || snake[-1] == "-") {
               snake = snake + Char.lower(c)
           } else {
               snake = snake + "_" + Char.lower(c)
           }
       } else {
           snake = snake + c
       }
   }
   return snake

}

var tests = [

   "snakeCase", "snake_case", "variable_10_case", "variable10Case", "ɛrgo rE tHis",
   "hurry-up-joe!", "c://my-docs/happy_Flag-Day/12.doc", "  spaces  "

]

System.print(" === to_snake_case ===") for (camel in tests) {

   Fmt.print("$33s -> $s", camel, toSnake.call(camel))

}

System.print("\n === toCamelCase ===") for (snake in tests) {

   Fmt.print("$33s -> $s", snake, toCamel.call(snake))

}</lang>

Output:
                          === to_snake_case ===
                        snakeCase -> snake_case
                       snake_case -> snake_case
                 variable_10_case -> variable_10_case
                   variable10Case -> variable10_case
                     ɛrgo rE tHis -> ɛrgo_r_e_t_his
                    hurry-up-joe! -> hurry-up-joe!
c://my-docs/happy_Flag-Day/12.doc -> c://my-docs/happy_flag-day/12.doc
                         spaces   -> spaces

                         === toCamelCase ===
                        snakeCase -> snakeCase
                       snake_case -> snakeCase
                 variable_10_case -> variable10Case
                   variable10Case -> variable10Case
                     ɛrgo rE tHis -> ɛrgoRETHis
                    hurry-up-joe! -> hurryUpJoe!
c://my-docs/happy_Flag-Day/12.doc -> c://myDocs/happyFlagDay/12.doc
                         spaces   -> spaces

XPL0

<lang XPL0>string 0; \use zero-terminated strings char Out(100); \output string (made global for safety)

func Trim(Str); \Trim leading and trailing spaces from string char Str; int I; [while Str(0) = $20 do Str:= Str+1; \skip leading spaces I:= 0; \skip to end of string (+1) while Str(I) # 0 do I:= I+1; while I>0 & Str(I-1)=$20 do I:= I-1; \skip back to first non-space Str(I):= 0; \chop off any trailing spaces return Str; ];

func ToSnake(In); \Convert string to snake_case char In; int I, J, C, UL; [I:= 0; J:= 0; UL:= true; \suppress leading & redundant underlines repeat C:= In(I); I:= I+1; \get character from input string

       if C>=^A & C<=^Z then           \convert uppercase to "_" + lowercase
               [if not UL then [Out(J):= ^_;  J:= J+1];
               Out(J):= C+$20;  J:= J+1;
               UL:= false;
               ]
       else if C=$20 or C=^- then      \convert to underlines
               [if not UL then [Out(J):= ^_;  J:= J+1;  UL:= true]
               ]
       else    [Out(J):= C;  J:= J+1;  UL:= C=^_];

until C = 0; return Out; ];

func ToCamel(In); \Convert string to camelCase char In; int I, J, C; [I:= 0; J:= 0; repeat C:= In(I); I:= I+1;

       if C=^_ or C=^- or C=$20 then
               [C:= In(I);  I:= I+1;
               if C>=^a & C<=^z then C:= C-$20;
               Out(J):= C;  J:= J+1;
               ]
       else    [Out(J):= C;   J:= J+1];

until C = 0; return Out; ];

int Strings, I; [Strings:= [

"snakeCase", "snake_case", "variable_10_case", "variable10Case", "\u025brgo rE tHis",
"hurry-up-joe!", "c://my-docs/happy_Flag-Day/12.doc", "  spaces  "];

Text(0, "To snake case:^M^J"); for I:= 0 to 7 do

   [Text(0, Strings(I));
   Text(0, " -> ");
   Text(0, ToSnake(Trim(Strings(I))));
   CrLf(0);
   ];

Text(0, "To camel case:^M^J"); for I:= 0 to 7 do

   [Text(0, Strings(I));
   Text(0, " -> ");
   Text(0, ToCamel(Trim(Strings(I))));
   CrLf(0);
   ];

]</lang>

Output:
To snake case:
snakeCase -> snake_case
snake_case -> snake_case
variable_10_case -> variable_10_case
variable10Case -> variable10_case
\u025brgo rE tHis -> \u025brgo_r_e_t_his
hurry-up-joe! -> hurry_up_joe!
c://my-docs/happy_Flag-Day/12.doc -> c://my_docs/happy_flag_day/12.doc
  spaces   -> spaces
To camel case:
snakeCase -> snakeCase
snake_case -> snakeCase
variable_10_case -> variable10Case
variable10Case -> variable10Case
\u025brgo rE tHis -> \u025brgoRETHis
hurry-up-joe! -> hurryUpJoe!
c://my-docs/happy_Flag-Day/12.doc -> c://myDocs/happyFlagDay/12.doc
  spaces -> spaces