Quick Guide from Perl to Javascript/ES6/Typescript
Long, Interpolated Strings¶
Perl:
my $str = qq{
This is a long
string in $language
};
JS:
const language = 'javascript';
const str = `
This is a long
string in ${language}
`;
Array push, pop, shift, unshift¶
Perl:
my @somearr;
push @somearr, ( 'something', 'foobar' );
my @another = ( 'quz', 'qar' );
push @another, @somearr;
shift @somearr;
pop @somearr;
unshift @somearr, 'more stuff';
# concat arrays:
my @newarr = ( @somearr, @another );
JS:
const somearr = [];
somearr.push('something','foobar');
const another = [ 'quz', 'qar' ];
somearr.push( ...another );
somearr.shift();
somearr.pop();
somearr.unshift('more stuff');
// concat arrays:
const newarr = somearr.concat(another);
Array iteration¶
Perl:
foreach my $it ( @someArray ) {
say $it;
}
JS:
for( const it of someArray ) {
console.log(it);
}
// or:
someArray.forEach( it => console.log(it) );
// or even shorter:
someArray.forEach( console.log );
Get a hash value¶
Perl:
my %hash = ( aa => 11, "long key" => 22, nested => { foo => 33 } );
print $hash{aa};
print $hash{'long key'};
print $hash{nested}{foo};
my $hashref = { aa => 11, "long key" => 22, nested => { foo => 33 } };
print $hashref->{aa};
print $hashref->{'long key'};
print $hashref->{nested}{foo};
JS:
const obj = { aa: 11, 'long key': 22, nested: { foo: 33 } };
console.log( obj.aa );
console.log( obj['aa'] );
console.log( obj['long key'] );
console.log( obj.nested.foo );
console.log( obj['nested']['foo'] );
Hash keys iteration¶
Perl:
for my $key ( keys %someHash ) {
...
}
JS:
for( const key of Object.keys(someHash) ) {
...
}
// or
Object.keys(someHash).forEach( key => { ... } );
Hash values iteration¶
Perl:
my %someHash = ( aa => 11, bb => 22 );
for my $val ( values %someHash ) {
// 11, 22
}
JS:
for( const val of Object.values(someHash) ) {
...
}
// or
Object.keys(someHash).forEach( key => { ... } );
Key-value hash iteration¶
Perl:
while( my ( $key, $val ) = each %someHash ) {
...
}
JS:
for( const [key,val] of Object.entries(someHash) ) {
...
}
Expand and merge array¶
Perl:
my @arrayMerged = ( 'aa', 'bb', @arrayA, @arrayB );
JS:
const arrayMerged = [ 'aa', 'bb', ...arrayA, ...arrayB ];
// or
const arrayMerged = [ 'aa', 'bb' ].concat(arrayA).concat(arrayB);
Merge hashes¶
Perl:
my %hashMerged = ( aa => 11, bb => 22, %hashA, %hashB );
JS:
const hashMerged = { aa: 11, bb: 22, ...hashA, ...hashB };
// or:
const hashMerged = Object.assign({ aa: 11, bb: 22 }, hashA, hashB );
// careful: Object.assign() changes the hash in place
const hashMerged = { aa: 11, bb: 22 };
Objecy.assign( hashMerged, hashA, hashB ); // hashMerged is changed in place
Delete a Hash key, and save value¶
Perl:
my $val = delete $someHash{ 'someKey' };
JS:
const val = someHash[someKey];
delete someHash[someKey]; // delete does not return a value
Create hash from variable keys and values¶
Perl:
my $key1 = 'aa';
my $value1 = 11;
my %someHash = { $key1 => $value1, $key2 => $value2 };
JS:
const key1 = 'aa';
const value1 = 11;
const someHash = { [key1]: value1, [key2]: value2 };
Map¶
Perl:
my $newArr = map { $_ + 1 } @someArr;
JS:
const newArr = someArr.map( it => it + 1 );
// or:
const newArr = someArr.map( it => {
return it + 1
});
Grep / Filter¶
Perl:
my @filtered = grep { $_ eq 'foo' } @someArr;
JS:
const filtered = someArr.filter( it => it === 'foo' );
Sorting alphabetically¶
Perl:
my @sortedAscending = sort { lc $a cmp lc $b } @unsortedArr;
my @sortedDescending = sort { lc $b cmp lc $a } @unsortedArr;
JS:
const sortedAscending = unsortedArr.sort((a = '', b = '') =>
a.toUpperCase().localeCompare(b.toUpperCase())
);
const sortedDescending = unsortedArr.sort((a = '', b = '') =>
b.toUpperCase().localeCompare(a.toUpperCase())
);
Convert Array to hash¶
Perl:
my %someHash = map { $_ => 1 } @someArray;
JS:
const someHash = someArray.reduce( (obj, val) => {
obj[val] = 1;
return obj;
}, {});
// shorter notation with comma:
const someHash = someArray.reduce( (obj, val) => (obj[val] = 1, obj) );
Deconstruct Array¶
Perl:
my @someArray = ( 11, 22, 33, 44 );
my ( $first, $second, @rest ) = @someArray;
JS:
const someArr = [ 11, 22, 33, 44 ];
const [ first, second, ...rest ] = someArr;
Deconstruct Hash¶
Perl:
my %someHash = ( aa => 11, bb => 22 );
my ( $aa, $bb ) = @{ \%someHash }{ qw( aa bb ) };
JS:
const someHash = { aa: 11, bb: 22, cc: 33, dd: 44 };
const { aa, bb } = someHash;
// you can also get the rest, cant easily do this in Perl
const { aa, bb, ...otherKeysInHash } = someHash;
Is value in array?¶
Perl:
if( 'foo' ~~ @someArr ) { ... }
JS:
if( someArr.includes('foo') ) { ... }
if( someArr.indexOf('foo') > -1 ) { ... }
Var is defined?¶
Perl:
if( defined $myvar ) {
...
}
JS:
if( myvar !== undefined ) {
...
}
Var is null/falsy/undefined?¶
Perl:
if( ! $myvar ) {
...
}
JS:
if( ! myvar ) {
...
}
Var is just null/undefined?¶
Perl:
if( ! length $myvar ) { # 0 and 1 are ok
...
}
JS:
if( myvar != null ) { // true, false, 0 and 1 are ok
...
}
OR undefined value¶
Perl:
my $val = $someVar // 'some default';
JS (ES2020/TS 3.7+):
const val = someVar ?? 'some default';
Subs/Functions¶
Perl:
sub myfunc {
my ( $x ) = @_;
$x //= 10; # a default value
return $x + $x;
}
JS:
function myfunc(x = 10) {
return x + x;
}
Subs/Functions in vars¶
Perl:
my $double = sub {
my ( $v ) = @_;
return $v * 2;
};
$double->(1234);
JS:
const double = v => v * 2;
double(1234);
// longform:
const double = v => {
return v * 2;
};
double(1234);
Get all function args as array¶
Perl:
sub myfunc {
for my $arg ( @_ ) {
}
}
JS:
function myfunc(...args) {
for( const arg of args ) {
}
}
Check if null/undef before calling method¶
Perl:
$obj->deploy if $obj;
JS (ES2020 or TS 3.7+):
obj?.deploy();
Check if member function exists:¶
Perl:
if( $obj->can('deploy') ) {
$obj->deploy;
}
JS:
obj?.deploy(); // TS or ES2020
// or
if( obj.deploy ) {
obj.deploy()
}
Simple Regular expression test¶
Perl:
if( $someStr =~ /foo/i ) { ... }
JS:
if( /foo/i.test(someStr) ) { ... }
Regular expression substitution¶
Perl:
$someStr =~ s/aaa (\d+)/bbb $1/gi;
JS:
someStr = someStr.replace(/aaa (\d+)/gi, 'bbb $1');
Regular expression loop all matches¶
Perl:
for( 'aaa bbb' =~ /\w+/g ) {
print "$_\n";
}
JS:
'aaa bbb'.match(/\w+/g).forEach( _ => {
console.log(_);
});
// or:
for( _ of 'aaa bbb'.match(/\w+/g) ) {
console.log(_);
}
Regular expression extraction¶
Perl:
my ( $a, $b ) = $someStr =~ /(aaa+*)(bbb+*)/;
JS:
const [ , a, b ] = /(aaa+*)(bbb+*)/.exec(someStr);
// or:
const [ , a, b ] = someStr.match(/(aaa+*)(bbb+*)/);
Regular expression named captures¶
Perl:
$someStr =~ /(?<myvar>foo)/;
print $+{myvar}; # foo
JS:
const { groups: { myvar } } = /(?<myvar>foo)/.exec(someStr);
console.log(myvar);
Regular expression precompiled¶
Perl:
my $re = qr/\w+/g;
for my $str ( @strs ) {
my @matches = $str =~ $re;
...
}
JS:
const re = new RegExp('\w+', 'g');
for( const str of strs ) {
const matches = re.exec(str);
...
}
Deconstructing with default values¶
Perl:
my $foo = $someHash{ foo } // 'mydefault';
my $bar = $someHash{ bar } // 11;
JS:
const { foo = 'mydefault', bar = {} } = someObj;
Check if is an Array, Object or a given class¶
Perl:
if( ref $myvar eq 'ARRAY' ) { ... }
elsif( ref $myvar eq 'HASH' ) { ... }
elsif( ref $myvar eq 'MyClass' ) { ... }
JS:
if( Array.isArray(myvar) ) { ... }
else if( typeof myvar === 'object' ) { ... } // careful: arrays are object too
else if( myvar instanceof MyClass ) { ... }
Using dates, convert from/to ISO¶
Perl:
# there's many ways to do it...
use POSIX qw(strftime);
my $now = localtime;
my $date = strftime "%m/%d/%Y", $now;
# parse it
my $format = DateTime::Format::Strptime->new( pattern => '%FT%T%z');
my $dt = $format->parse_datetime( '2017-04-09T21:00:00-0400' );
# or
use DateTime;
my $now = DateTime->now()->iso8601();
JS:
const now = new Date();
const date = now.toISOString().substring(0,10);
// parse it
const nowAgain = new Date(date); // sets time to midnight UTC
// today with timezone
const nowInNYC = new Date().toLocaleString("en-US", {timeZone: "America/New_York"})