Schrift
[thread]7574[/thread]

Mehrdimensionales Array: Mehrdimensionales Array aus einem file e



<< >> 8 Einträge, 1 Seite
Gast Gast
 2005-12-23 12:21
#61334 #61334
Hallo,

ich hätte eine wahrscheinlich für euch leichte Frage,
da ich aber recht neu auf dem Gebiet bin, weis ich leider nicht wie ich das angehe.

Ich habe folgendes file mit folgendem Inhalt (abgespeckte Version):

KWER02;262;P1-3-1-1-5-2.0;80077
KWER02;15;P1-3-1-1-5-2.0;80078
KWER02;262;P1-3-1-1-5-1.0;80078
KWER02;15;P1-3-1-1-1-1.0;80093
TDUI01;46;P4-5-1.83;82180
WCOL02;13;P1-1-2-4.0.100;81684
KWER02;14;P1-3-1-1-1-1.0;80091
KWER02;262;P1-3-1-1-1-1.0;80092
WCOL02;14;P1-1-2-4.0.100;81685
WCOL02;15;P1-1-2-4.0.100;81686
WCOL02;13;P1-1-2-4.0.116;81687
TDUI01;46;P2-8-1.75;82189
SJAK01;46;P2-8-3.0;82197
TDUI01;46;P2-10-1.80;82198

Jetzt möchte ich ein mehrdimensionales Array erzeugen.
Normalerweise ist das ja ganz leicht, ich möchte aber das nichts
doppeltes vorkommt, da ich das array fürs suchen verwenden muß.

Und das ganze für die Spalten 1, 2 und 3.
Bei der Spalte 4 gibt es keine gleichen Einträge.

Sollte also dann ca so aussehen:

$arr[0] .. KWER02
$arr[1] .. TDUI01
...

$arr[0][0] ... 262
$arr[0][1] ... 15

Ich hoffe Ihr kennt euch aus was ich meine.

Danke schon mal im voraus, ihr würdet mir damit sehr helfen.
Ich probier das jetzt schon 2 Tage ohne Erfolg.

Danke
lg
Christoph
format_c
 2005-12-23 12:33
#61335 #61335
User since
2003-08-04
1706 Artikel
HausmeisterIn
[Homepage] [default_avatar]
naja fast.
so ungefähr würde der perl code aussehen
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
use strict;
use Data::Dumper;

my @data = ();
my $string = qq~KWER02;262;P1-3-1-1-5-2.0;80077
KWER02;15;P1-3-1-1-5-2.0;80078
KWER02;262;P1-3-1-1-5-1.0;80078~;

for (split(/\r?\n/,$string)) {
 push(@data,[split(/;/)]);
}

print Dumper(\@data);

siehe perldoc -f split

Edit:
Wenn die Daten durch ein Filehandle kommen würde das in etwa so aussehen:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
use strict;
use Data::Dumper;

my @data = ();

while (<DATA>) {
 push(@data,[split(/;/)]);
}

print $data[0]->[1];
_ _DATA_ _
KWER02;262;P1-3-1-1-5-2.0;80077
KWER02;15;P1-3-1-1-5-2.0;80078
KWER02;262;P1-3-1-1-5-1.0;80078


Würde dann in etwa so eine Datenstruktur erzeugen:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$VAR1 = [
         [
           'KWER02',
           '262',
           'P1-3-1-1-5-2.0',
           '80077'
         ],
         [
           'KWER02',
           '15',
           'P1-3-1-1-5-2.0',
           '80078'
         ],
         [
           'KWER02',
           '262',
           'P1-3-1-1-5-1.0',
           '80078'
         ],

...


Also mit $data[2]->[1] würde "262" ausgegeben werden.
Gruß Alex\n\n

<!--EDIT|format_c|1135334266-->
Ronnie
 2005-12-23 12:44
#61336 #61336
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
Ein Hash of Array ist hier sinnvoller:
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
#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my %lut;

while (<DATA>) {
chomp;
my @cur = split(/;/);
push @{$lut{$cur[0]}}, [@cur[1..$#cur]];
}

print Dumper \%lut;

_ _DATA_ _
KWER02;262;P1-3-1-1-5-2.0;80077
KWER02;15;P1-3-1-1-5-2.0;80078
KWER02;262;P1-3-1-1-5-1.0;80078
KWER02;15;P1-3-1-1-1-1.0;80093
TDUI01;46;P4-5-1.83;82180
WCOL02;13;P1-1-2-4.0.100;81684
KWER02;14;P1-3-1-1-1-1.0;80091
KWER02;262;P1-3-1-1-1-1.0;80092
WCOL02;14;P1-1-2-4.0.100;81685
WCOL02;15;P1-1-2-4.0.100;81686
WCOL02;13;P1-1-2-4.0.116;81687
TDUI01;46;P2-8-1.75;82189
SJAK01;46;P2-8-3.0;82197
TDUI01;46;P2-10-1.80;82198

Achtung: Die _ _ müssen zusammengeschrieben werden.
chrisidc
 2006-01-26 17:12
#61337 #61337
User since
2006-01-26
8 Artikel
BenutzerIn
[default_avatar]
Hallo Ronnie,

danke für die Hilfe.
Ich hätte jedoch noch eine Frage dazu,
weil ich nicht weis wie ich solche "Hash of Arrays" ansprechen kann.

Ich habe ein zweites file und gehe diese Zeile für Zeile mit

Code: (dl )
1
2
3
4
5
6
7
open(FILE2, "file2");
while (<TESTFILE>) {

#Hier fehlt mir der code weil ich nicht weis wie ich das "Hash of Arrays" anspreche.

}
close(FILE2);


durch.

Der Inhalt von file2 sieht wie folgt aus:
2006/01/26,Pfad,46,SJAK01/P2-8-1.0,3263422
2006/01/26,E1,13,WCOL02/P1-1-2-4.0.100,0
2006/01/26,E1,262,KWER02/P1-3-1-1-5-2.0,534
...u.s.w.


Schlußendlich möchte ich bei Zeile 3 (von File2) vom "Hash of Array" den Wert 80077 zurückbekommen.

Hash of Array verwende ich deshalb um die Performance zu steigern. File1 (das dann das Hash of Array wird) hat ca. 1,1 MB und File2 hat ca. 3,2 MB.
Wenn ich also jede Zeile von File2 hernehme und in File1 suche dauert das zu lange (mehr als 24 Stunden). Ich hätte aber gerne dass das in ca. 15-30 Minuten erledigt ist.
Vielleicht hast du ja auch noch eine andere Idee wie ich die Performance steigern kann.

Sollte etwas unklar sein bitte melden und sorry für die späte Antwort aber ich hatte leider in den letzten Tagen keine Zeit.

Vielen Dank
Grüße Christoph
Strat
 2006-01-26 18:15
#61338 #61338
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
da brauchst du zuerst mal den schluessel (nennen wir ihn mal $key; aber du findest da sicher Variablennamen, die den inhalt besser beschreiben), der bei dir in spalte 4 ist
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
my $file = "file2";
open (my $FILE, "<", $file) or die "Error in reading '$file': $!\n";
while (my $line = <$FILE>) {
chomp($line); # zeilenumbruch am ende weg

my @columns = split(/,/, $line); # aufsplitten
my $key = $columns[3]; # 0,1,2,3

if (exists $lut{$key}) { # ist was vorhanden?

# entweder die lange version
my @fields = @{ $lut{$key} }; # komplett dereferenzieren
print "@columns: Ergebnis: $fields[2]\n";

# oder kuerzer, ohne @fields in einer zeile:
# print "@columns: Ergebnis: $lut{$key}->[2]\n";
} # if

else {
print "Fehler: fuer '$key' jibbet nix\n";
} # else
} # while
close ($FILE);

wenn das CSV-Format etwas komplexer wird (z.B. duerfen auch \, in den werten vorkommen, dann funktioniert das einfache split nicht mehr; da dann besser CPAN:Text::CSV oder CPAN:Text::CSV_XS (zweites ist schneller) verwenden.\n\n

<!--EDIT|Strat|1138292158-->
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
chrisidc
 2006-01-27 00:13
#61339 #61339
User since
2006-01-26
8 Artikel
BenutzerIn
[default_avatar]
Hallo,

danke aber leider funkt es irgendwie noch nicht ganz.

Ich habe ja in dem Hash of Array z.B. kein SJAK01/P2-8-1.0
sonder SJAK01 ist eine eigene Spalte und P2-8-1.0 ist eine eigene Spalte.

Ich habe deshalb den Code ein bisserl abgeändert:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
my $file = "file2";
open (my $FILE, "<", $file) or die "Error in reading '$file': $!\n";
while (my $line = <$FILE>) {
chomp($line); # zeilenumbruch am ende weg

my @columns = split(/,/, $line); # aufsplitten
my @temp = split(/\//, $columns[3]); # aufsplitten
my $key = $temp[0]; # 0,1,2,3

if (exists $lut{$key}) { # ist was vorhanden?

# entweder die lange version
my @fields = @{ $lut{$key} }; # komplett dereferenzieren
print "@columns: Ergebnis: $fields[2]\n";

# oder kuerzer, ohne @fields in einer zeile:
# print "@columns: Ergebnis: $lut{$key}->[2]\n";
} # if

} # while

close ($FILE);

Habe also noch ein split eingebaut.
Irgendwie kommt aber dann als Ergebnis nur folgendes zurück:
... Ergebnis: ARRAY(0x1c90d8)

Soll ich vielleicht mein ganzes Problem nochmals neu erklären?

Danke
Grüße
Christoph
renee
 2006-01-27 00:43
#61340 #61340
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Probier mal:
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
#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my %lut;
my $file1 = './file1.txt';
my $file2 = './file2.txt';

open(my $fh,"<",$file1) or die $!;
while (<$fh>) {
chomp;
my @cur = split(/;/);
push @{$lut{$cur[0]}->{$cur[2]}->{$cur[1]}}, $cur[3];
}
close $fh;

open(my $fh2,"<",$file2) or die $!;
while(<$fh2>){
my ($number,$path) = (split(/,/,$_))[2,3];
my ($path1,$path2) = split(/\//,$path);
if(exists $lut{$path1}->{$path2}->{$number}){
my $string = join(" # ",@{$lut{$path1}->{$path2}->{$number}});
print $string,"\n";
}
}
close $fh2;


Getestet mit folgenden Dateien:
file1.txt
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
KWER02;262;P1-3-1-1-5-2.0;80077
KWER02;15;P1-3-1-1-5-2.0;80078
KWER02;262;P1-3-1-1-5-1.0;80078
KWER02;15;P1-3-1-1-1-1.0;80093
TDUI01;46;P4-5-1.83;82180
WCOL02;13;P1-1-2-4.0.100;81684
KWER02;14;P1-3-1-1-1-1.0;80091
KWER02;262;P1-3-1-1-1-1.0;80092
WCOL02;14;P1-1-2-4.0.100;81685
WCOL02;15;P1-1-2-4.0.100;81686
WCOL02;13;P1-1-2-4.0.116;81687
TDUI01;46;P2-8-1.75;82189
SJAK01;46;P2-8-3.0;82197
TDUI01;46;P2-10-1.80;82198


file2.txt
Code: (dl )
1
2
3
2006/01/26,Pfad,46,SJAK01/P2-8-1.0,3263422
2006/01/26,E1,13,WCOL02/P1-1-2-4.0.100,0
2006/01/26,E1,262,KWER02/P1-3-1-1-5-2.0,53
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
chrisidc
 2006-01-28 15:43
#61341 #61341
User since
2006-01-26
8 Artikel
BenutzerIn
[default_avatar]
Hallo,

danke euch allen jetzt funktioniert es wunderbar.

Grüße
Christoph
<< >> 8 Einträge, 1 Seite



View all threads created 2005-12-23 12:21.