Good evening: whale2:
What should I do with a sample that writes a process such as dictionary [key] + = 1
in each language and a language that displays a message such as" There is no such key "in that process? (Difficult to convey)
The execution environment is as follows.
environment
#Computer
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.12.1
BuildVersion: 16B2555
# Ruby
$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin16]
# Perl
$ perl -v | grep v5
This is perl 5, version 24, subversion 0 (v5.24.0) built for darwin-thread-multi-2level
# Perl6
$ perl6 -v
This is Rakudo version 2016.07.1 built on MoarVM version 2016.07
implementing Perl 6.c.
# Python
$ python --version
Python 3.5.1 :: Anaconda 4.1.0 (x86_64)
# PHP5
$ php -v
PHP 5.6.25 (cli) (built: Sep 6 2016 16:37:16)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
Ruby
error
target = %w[a a b b c 0 1 1 1]
count = {}
target.each{|var|
count[ var ] += 1
}
puts count
=begin
#=>error
inc.rb:5:in `block in <main>': undefined method `+' for nil:NilClass (NoMethodError)
from inc.rb:4:in `each'
from inc.rb:4:in `<main>'
=end
Ruby is beautiful.
inc.rb
target = %w[a a b b c 0 1 1 1]
count = Hash.new(0) #Set initial value
target.each{|var|
count[ var ] += 1
}
puts count #=> {"a"=>2, "b"=>2, "c"=>1, "0"=>1, "1"=>3}
inc2.rb
target = %w[a a b b c 0 1 1 1]
count = {}
count.default = 0 #Set initial value
target.each{|var|
count[ var ] += 1
}
puts count #=> {"a"=>2, "b"=>2, "c"=>1, "0"=>1, "1"=>3}
Python
error
target = 'a a b b c 0 1 1 1'.split(' ')
count = {}
for var in target:
count[ var ] += 1
print( count )
'''
#=>error
Traceback (most recent call last):
File "inc.py", line 6, in <module>
count[ var ] += 1
KeyError: 'a'
'''
Python seems to have a better way.
inc.py
target = 'a a b b c 0 1 1 1'.split(' ')
count = {}
for var in target:
count.setdefault( var, 0 )
count[ var ] += 1
print( count ) #=> {'a': 2, '1': 3, '0': 1, 'c': 1, 'b': 2}
How to use defaultdict (). @Mpyw told me in the comments.
Python::inc2.py
from collections import defaultdict
target = 'a a b b c 0 1 1 1'.split(' ')
count = defaultdict(int)
for var in target:
count[ var ] += 1
print( count ) #=> defaultdict(<class 'int'>, {'b': 2, '1': 3, '0': 1, 'a': 2, 'c': 1})
How to write exception handling. It seems to be applicable to any language. Nice.
inc3.py
target = 'a a b b c 0 1 1 1'.split(' ')
count = {}
for var in target:
try:
count[ var ] += 1
except KeyError:
count[ var ] = 1
print( count )
PHP
I get an Undefined index Notice message, although it is not an error. ~~ ʻerror_reporting (-1);` must be written ~~
Notice
<?php
error_reporting( -1 );
$target = explode(' ', 'a a b b c 0 1 1 1');
$count = [];
foreach( $target as $var ){
$count[ $var ] += 1;
}
echo json_encode( $count ) . PHP_EOL ;
/*
#=>
Notice: Undefined index: a in /Users/yuhei/inc.php on line 8
Notice: Undefined index: b in /Users/yuhei/inc.php on line 8
Notice: Undefined index: c in /Users/yuhei/inc.php on line 8
Notice: Undefined offset: 0 in /Users/yuhei/inc.php on line 8
Notice: Undefined offset: 1 in /Users/yuhei/inc.php on line 8
{"a":2,"b":2,"c":1,"0":1,"1":3}
*/
Do not suppress the error (commandment)
not recommended
<?php
error_reporting( -1 );
$target = explode(' ', 'a a b b c 0 1 1 1');
$count = [];
foreach( $target as $var ){
@$count[ $var ] += 1; #Error suppression
}
echo json_encode( $count ) . PHP_EOL ; #=> {"a":2,"b":2,"c":1,"0":1,"1":3}
Substitute 1 if there is no key. Added a conditional branch.
isset()
<?php
error_reporting( -1 );
$target = explode(' ', 'a a b b c 0 1 1 1');
$count = [];
foreach( $target as $var ){
if( isset( $count[ $var ] ) ){
$count[ $var ] += 1;
}
else{
$count[ $var ] = 1;
}
}
echo json_encode( $count ) . PHP_EOL ; #=> {"a":2,"b":2,"c":1,"0":1,"1":3}
For this example, I think the built-in function ʻarray_count_values ()` is good.
array_count_values()
<?php
error_reporting( -1 );
$target = explode(' ', 'a a b b c 0 1 1 1');
$count = array_count_values( $target );
echo json_encode( $count ) . PHP_EOL ; #=> {"a":2,"b":2,"c":1,"0":1,"1":3}
ʻAssign 1 if there is no key in array_count_values ()`. Increment if there is a key. It seems that the process is being performed. (It's also nice to check that the key is a number or a string)
C:php-5.6.27/ext/standard/array.c
/* {{{ proto array array_count_values(array input)
Return the value as key and the frequency of that value in input as value */
PHP_FUNCTION(array_count_values)
{
zval *input, /* Input array */
**entry, /* An entry in the input array */
**tmp;
HashTable *myht;
HashPosition pos;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &input) == FAILURE) {
return;
}
/* Initialize return array */
array_init(return_value);
/* Go through input array and add values to the return array */
myht = Z_ARRVAL_P(input);
zend_hash_internal_pointer_reset_ex(myht, &pos);
while (zend_hash_get_current_data_ex(myht, (void **)&entry, &pos) == SUCCESS) {
if (Z_TYPE_PP(entry) == IS_LONG) {
if (zend_hash_index_find(Z_ARRVAL_P(return_value), Z_LVAL_PP(entry), (void **)&tmp) == FAILURE) {
zval *data;
MAKE_STD_ZVAL(data);
ZVAL_LONG(data, 1);
zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_PP(entry), &data, sizeof(data), NULL);
} else {
Z_LVAL_PP(tmp)++;
}
} else if (Z_TYPE_PP(entry) == IS_STRING) {
if (zend_symtable_find(Z_ARRVAL_P(return_value), Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, (void**)&tmp) == FAILURE) {
zval *data;
MAKE_STD_ZVAL(data);
ZVAL_LONG(data, 1);
zend_symtable_update(Z_ARRVAL_P(return_value), Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, &data, sizeof(data), NULL);
} else {
Z_LVAL_PP(tmp)++;
}
} else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only count STRING and INTEGER values!");
}
zend_hash_move_forward_ex(myht, &pos);
}
}
/* }}} */
Perl Perl is the best without error.
inc.pl
use v5.24;
use warnings;
use Data::Dumper;
my @target = qw[a a b b c 0 1 1 1];
my %count;
for my $var ( @target ){
$count{ $var } += 1;
}
print Dumper \%count;
__DATA__
#=>
$VAR1 = {
'c' => 1,
'1' => 3,
'b' => 2,
'a' => 2,
'0' => 1
};
Perl6 Perl 6 best (ry) that does not cause an error
inc.pl6
use v6;
my @target = <a a b b c 0 1 1 1>;
my %count;
for @target -> Str $var {
%count{ $var } += 1;
}
%count.say; #=> {0 => 1, 1 => 3, a => 2, b => 2, c => 1}
Stabbed by people in each language: whale2:
Recommended Posts