Also, gemäß dem PCE-Wiki ist es so, dass wenn ein Array im alten Hash eine andere Datenstruktur besitzt als das Array an gleicher Posotion im neuen Hash, dort die alte Datenstruktur behalten soll. Mir leuchtet das zwar nicht so wirklich ein was daran sinnvoll sein soll, aber ich habe mal eingebaut, dass man entscheiden kann, was dort getan werden soll.
Was ich noch nicht habe: Partiell gleiche Arrays. Da gabs keine Vorgaben. Vorschläge?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/Perl/bin/perl
use strict;
use warnings;
use Data::Dumper qw/Dumper/;
$Data::Dumper::Sortkeys = 1;
$HASH::Update::beiArrayMitUngleichenElementenAlterDatensatz = 0;
my $alt = {
key1 => "Ich bin immer noch da",
key2 => "Ich werde ersatzlos gestrichen",
key3 => {
"key3-1" => "Ich bin immer noch da"
},
key4 => [qw(Ich werde ersatzlos gestrichen)],
key7 => [qw(Ich bin immer noch da)],
key8 => ['alt', 'scalar', {'alt_hash' => 'alt_value'}, ],
};
my $neu = {
key1 => "Ich werde überschrieben",
key3 => {
"key3-1" => "Ich werde überschrieben",
"key3-2" => "Ich bin neu dazugekommen"
},
key5 => "Ich bin neu dazugekommen",
key6 => [qw (Ich bin neu dazu gekommen)],
key7 => [qw (Ich werde überschrieben)],
key8 => [qw(neu scalar scalar)],
};
sub hash_update {
# $_[0] = alt; $_[1] = neu;
#my $alt = shift;
#my $neu = shift; # alles in der Referenz ändern!
# Für Rekursion: stimmen die übergebenen Datenstrukturen nicht überin
# so wird in der neuen Datensturkur nichts geändert.
return unless ref $_[0] eq ref $_[1];
# Ist es ein Skalar? Ein Array? Ein Hash?
if( ref $_[1] eq "HASH" ) {
# Es ist ein Arschloch - äh, nein, ein Hash.
# Alle Werte im neuen Hash sollen mit den Werten aus
# dem alten Hash geupdated werden, wenn sie dort mit
# dem gleichen Schlüssel und in gleicher Form
# (Datenstruktur) vorliegen.
foreach my $s_neu ( keys %{$_[1]} ) {
# Gibt es den Schlüssel im alten Hash?
if( exists $_[0]->{$s_neu}
# ist es die Gleiche Datenstruktur?
# Wenn nicht soll die neue übernommen werden.
and ref $_[0]->{$s_neu} eq ref $_[1]->{$s_neu} ) {
# Rekursuion...
#print "hash: rekursion mit $s_neu\n";
hash_update($_[0]->{$s_neu}, $_[1]->{$s_neu});
}
}
}elsif( ref $_[1] eq "ARRAY" ) {
# Es ist ein Array. Durchlaufe alle Einträge ud prüfe, ob die
# alte Datenstruktur mit der neuen übereinstimmt.
# Ist die Datenstruktur gleich, dann Rekursion mit allen Elementen.
if( compare_arrays($_[0], $_[1]) ) {
# öhm, scalar @{$_[0]} ???
print "array-comp: " . scalar @{$_[0]} . " => " . scalar @{$_[1]} . "\n";
for( my $c = 0; $c < scalar @{$_[0]}; $c++ ) {
hash_update($_[0]->[$c], $_[1]->[$c]);
}
}else{
print "array-comp: " . scalar @{$_[0]} . " => " . scalar @{$_[1]} . "\n";
# Entscheide anhand der gesetzten Umgebungsvariablen ob bei
# ungleicher Anzahl von Elementen der alte oder der neue Eintrag
# genommen werden soll.
if( $HASH::Update::beiArrayMitUngleichenElementenAlterDatensatz ) {
$_[1] = $_[0];
}
}
# ???
# Ist die Datenstruktur partiell gleich, dann solange Rekursion wie
# gleich, ansonsten altes belassen + neues hinzufügen???
# zu faul...
}else{
# Es ist ein Skalar. Existiert der Wert in der alten Datenstruktur
# wird er übernommen.
#print "$_[0] => $_[1]\n";
$_[1] = $_[0];
}
} # /hash_update
# Funktion zum Vergleichen zweier Arrays auf Äquivalenz
# vgl. perlfaq4, "How do I test whether two arrays or hashes are equal?"
sub compare_arrays {
my ($first, $second) = @_;
no warnings; # silence spurious -w undef complaints
return 0 unless @$first == @$second;
for (my $i = 0; $i < @$first; $i++) {
# heir "ref" hinzugefügt, weil ich wissen will, ob die
# Datenstruktur gleich ist, nicht der Inhalt.
return 0 if ref $first->[$i] ne ref $second->[$i];
}
return 1;
}
hash_update($alt, $neu);
print Dumper( $neu );
EDIT: Smileys killen...\n\n
<!--EDIT|pktm|1148568158-->