我正在从日志文件中提取数据,并希望将数据插入哈希中。我的问题是散列具有重复的值,我无法弄清楚如何忽略已经存在的值。我的代码如下:
ReservedNames
输出看起来像这样:
type ReservedNames = "this" | "that"
type FooName = Exclude<string, ReservedNames>;
const f1 : FooName = "This" // Works
const f2 : FooName = "this" // Should error
function withName<T extends string>(v: T & (T extends ReservedNames ? "Value is reserved!": {})) {
return v;
}
withName("this"); // Type '"this"' is not assignable to type '"Value is reserved!"'.
withName("This") // ok
如何从哈希表中删除这些重复项?预先感谢。
答案 0 :(得分:3)
如果您不关心时间戳的顺序,请使用哈希引用而不是数组。
while(my $line = <$fh> ) {
$line =~ /^\s*([\d.]+) ([\d:]+) --- (.*) -.*\s*$/;
my $timestamp = join(" ", $1, $2);
my $action = $3;
# use a counting hash instead of a list
$results{$action}->{$timestamp}++;
}
您的结构现在有所不同。
'Start Ermittlung der Freibeträge Gesamt.' => {
'01.06.2018 03:54:49' => 4,
'07.06.2018 03:14:45' => 4,
'31.05.2018 03:28:45' => 4,
'08.06.2018 03:33:36' => 4,
'02.06.2018 03:30:11' => 4,
},
要访问时间戳,您需要使用keys
。
say for sort keys %{ $results{$action} };
当然,由于德国日期是DD.MM.YYYY
而不是YYYY-MM-DD
,因此排序错误。但是您应该使用sort
,因为哈希顺序在设计上是不可靠的,因此每次运行的程序都会为您提供随机排列的输出。
答案 1 :(得分:0)
由于时间戳是有序的,
while(my $line = <$fh> ) {
my ($ts, $action) = $line =~ /^\s*([\d.]+ [\d:]+) --- (.*) -/;
my $actions = $results{$action} //= [];
push @$actions, $ts
if !@$actions
|| $actions->[-1] ne $ts;
}
如果我误以为要订购的时间戳记,这是一种替代方法。
哈希不仅可用于分组;它们对于删除重复项也很有用。以下是删除重复项的惯用方式(在保留顺序的同时):
my %seen;
@a = grep { !$seen{$_}++ } @a;
您可以按如下所示将此方法应用于您的解决方案:
my %seen;
my %results;
while(my $line = <$fh> ) {
my ($ts, $action) = $line =~ /^\s*([\d.]+ [\d:]+) --- (.*) -/;
push @{ $results{$action} }, $ts
if !$seen{$action}{$ts}++;
}
答案 2 :(得分:0)
尝试一下:
while(my $line=<F>) {
# logfile pattern 31.05.2018 03:25:50 --- Start Deaktiviere PKonten ---
$line =~ /^\s*([\d.]+) ([\d:]+) --- (.*) -.*\s*$/;
$timestamp=join(" ",$1,$2);
$action=$3;
my $value_in_array = grep {$_ eq $timestamp} @{$results{$action}};
push(@{$results{$action}} ,$timestamp)
unless($value_in_array) ;
}
答案 3 :(得分:-1)
如果要从数组引用中删除重复项,则可以采用这种方法。在建立散列后,它将删除重复项。
while(my $line=<F>) {
# logfile pattern 31.05.2018 03:25:50 --- Start Deaktiviere PKonten ---
$line =~ /^\s*([\d.]+) ([\d:]+) --- (.*) -.*\s*$/;
$timestamp=join(" ",$1,$2);
$action=$3;
push @{$results{$action}} ,$timestamp;
}
foreach my $key (keys %result) {
$result{$key} = [keys %{ {map {$_ => 1} @{$result{$key}}} }];
}
此解决方案应在构建散列时过滤数据:
my %filter;
while(my $line=<F>) {
# logfile pattern 31.05.2018 03:25:50 --- Start Deaktiviere PKonten ---
$line =~ /^\s*([\d.]+) ([\d:]+) --- (.*) -.*\s*$/;
$timestamp=join(" ",$1,$2);
$action=$3;
if(!defined $filter{$action}{$timestamp}) {
push @{$results{$action}} ,$timestamp;
$filter{$action}{$timestamp} = 1;
}
}