Schrift
[thread]8948[/thread]

Ein Hash nach bestimmten Vorgaben füllen



<< >> 2 Einträge, 1 Seite
mordur
 2007-04-26 16:39
#76260 #76260
User since
2003-09-25
182 Artikel
BenutzerIn
[Homepage] [default_avatar]
moins,

ich habe in einer Datenbank folgende Tabelle:

Cid >> sharednetworkID
6 >> 2
1 >> 3
7 >> 3

jetzt soll ein Hash erstellt werden, welches am Ende so aussieht:

für die Cid 6 Einträge wie folgt:
$hash->{6}->{START} = 'Y'
$hash->{6}->{Content} = 'Y'
$hash->{6}->{ENDE} = 'Y'

für die Cid 1 und 7 wird es komplizierter, da diese durch die gleiche sharednetworkID zusammengehören.
Die Hasheinträge sollen dann so aussehen:

$hash->{1}->{START} = 'Y'
$hash->{1}->{Content} = 'Y'
$hash->{1}->{ENDE} = 'N'

$hash->{7}->{START} = 'N'
$hash->{7}->{Content} = 'Y'
$hash->{7}->{ENDE} = 'Y'

Es ist möglich das noch eine Cid mit der gleichen sharednetworkID wie für Cid 1 und 7 dazukommt, zb. 4. Dann sollte der Hash folgendermassen aussehen.



$hash->{1}->{START} = 'Y'
$hash->{1}->{Content} = 'Y'
$hash->{1}->{ENDE} = 'N'

$hash->{4}->{START} = 'N'
$hash->{4}->{Content} = 'Y'
$hash->{4}->{ENDE} = 'N'

$hash->{7}->{START} = 'N'
$hash->{7}->{Content} = 'Y'
$hash->{7}->{ENDE} = 'Y'

Also einen ContentSchlüssel benötige ich immer, die anderen abhängig von der sharedNetworkID und der Anzahl Cid mit der gleichen sharedNetworkID.

Hat jemand eine Idee oder einen Ansatz für eine Lösung?

mfg mordur
PerlProfi
 2007-04-26 18:48
#76261 #76261
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Du kannst ja die Daten nach den sharednetworkIDs sortieren und dir jede einzeln merken.

Hier ein Beispiel:
Code: (dl )
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
#!/usr/bin/perl
use strict;
use warnings 'all';
use Data::Dumper;

# get ids
my $text =
'1 << 3'."\n".
'5 << 2'."\n".
'3 << 2'."\n".
'9 << 5'."\n".
'8 << 2'."\n".
'7 << 5'."\n".
'2 << 5'."\n".
'4 << 4';

# sort the ids
my @sorted = sort { $a->[1] <=> $b->[1] }
map { [split(/\s*<<\s*/, $_)] }
split("\n", $text);

# initialize the data hash, the hash for array checking
# and our actual position
my($hash, $last) = ({}, {});
my $actpos = 0;

# iterate through the sorted ids
foreach (@sorted)
{
# get cid and sharednetworkid
my($cid, $snid) = (@{$_});

# set start and content
my($start, $content, $end) = ($actpos, 'x'x($actpos+$cid));

# check whether we have an array
if (defined($last->{$snid}))
{ $start = $hash->{$last->{$snid}}->{END} }

# set end
$end = length($content) + $start;

# increment actual position
$actpos = $end + 1;

# create hash items
$hash->{$cid} = {START => $start,
CONTENT => $content,
END => $end};

# set last sharednetworkid
$last->{$snid} = $cid;
}

# output
$Data::Dumper::Sortkeys = 1;
print Dumper($hash);

Die IDs sind hier am Anfang in einem Skalar.
Mit split() und map{} trenne ich die IDs voneinander und mit sort{} sortiere ich sie nach der sharednetwordID, dass Ergebnis wird dann @sorted zugewiesen.

In $hash werden die Daten gesammelt.
In $last speichere ich zu jeder sharednetword ID deren Platz in $hash.
$actpos ist die aktuelle Position beim einsortieren der Daten.
Durch das Sortieren am Anfang wird sichergestellt, dass sich keine Einträge aus $hash überschneiden. Also dass jeder Eintrag seinen Bereich von START zu END bekommt und kein anderer Eintrag einen Teil dieses Bereichs mitnutzt.

An der Ausgabe kann man schön erkennen, dass z.B. die Cids 5, 3 und 8 zusammengehören, da der END Punkt des einen jeweils der START Punkt eines anderen ist.

MfG
<< >> 2 Einträge, 1 Seite



View all threads created 2007-04-26 16:39.