perl_krish has asked for the wisdom of the Perl Monks concerning the following question:

This node falls below the community's minimum standard of quality and will not be displayed.

Replies are listed 'Best First'.
Re: Tricky Problem
by edan (Curate) on Aug 19, 2004 at 13:33 UTC

    If you want other people to critique your logic, it's usually helpful to provide them with your code.

    How about you show us what you did, and explain what you like, what you don't like, why you think the way you did it isn't the best way, and so on. Then maybe you'll get some helpful responses.

    This is much better then just expecting other people to solve your problem from scratch.

    --
    edan

Re: Tricky Problem
by Aristotle (Chancellor) on Aug 19, 2004 at 13:36 UTC

    The trickiest part about your problem is that we don't know what it is. Can you tell us what "read" means in your case?

    As far as the count of lines is concerned, there is any number of ways. If you slurp the file to an array, you can just look at how many elements the array has. If you read it in a while loop, you could look at the $. special variable afterwards. Or you could count newline characters using tr///. What is easiest and/or most efficient depends on the context in which you're doing it.

    Makeshifts last the longest.

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Tricky Problem
by ccn (Vicar) on Aug 19, 2004 at 13:47 UTC

    #!/usr/bin/perl -w use strict; my %H; while (<DATA>) { /^(\d\d\d)-(\d\d\d),(\w\w),(.*)/ or die "Can't parse $_"; push @{$H{$1}{$3}{head}}, $2; push @{$H{$1}{$3}{tail}}, grep{$_} split ':', $4; } foreach my $k1 (sort {$a <=> $b} keys %H) { print "$k1\n"; foreach my $k2 (sort {$a <=> $b} keys %{$H{$k1}}) { print "$k2\n"; my $tail = join ':', sort {$a <=> $b} @{$H{$k1}{$k2}{tail}}; foreach my $head (sort {$a <=> $b} @{$H{$k1}{$k2}{head}}) { print "$head|$tail\n"; } } } __DATA__ 100-233,MA,150:250 100-344,MA,350: 200-400,ER, 200-300,ER,576
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Tricky Problem
by Jaap (Curate) on Aug 19, 2004 at 13:32 UTC
    What do you have so far? Show us your Perl code please.
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Tricky Problem
by atcroft (Abbot) on Aug 19, 2004 at 15:47 UTC

    It looks like you're trying to do something reminiscent of dealing with schedules or availablity, but that is just supposition. Your output, however, looks like it could be done with a complex data structure. (I have also included the data Jasper inquired about, to show how it would be handled by this untested sample code as well.)

    my (%data); while (<DATA>) { chomp; # $_ contains '100-233,MA,150:250', for example my @initialparts = split( /,/, $_ ); # @initialparts now contains ( '100-233', 'MA', '150:250' ) my @leadparts = split( /-/, $initialparts[0]); # @leadparts now contains ( '100', '233' ) push( @{$data{$leadparts[0]}{$initialparts[1]}{'items'}, $leadparts[1] ); # @{$data{'100'}{'MA'}{'items'} = ( '233' ) if (scalar(@initialparts) > 2) { # Do only if there was a last term my @tailparts = split( /:/, $initialparts[2] ); # @tailparts now contains ( '150', '250' ) push( @{$data{$leadparts[0]}{$initialparts[1]}{'data'}, @tailparts ); } } open(OUTF, $0 . '.out') or die("Can't open $0.out for output: $!\n"); foreach my $f1 (sort(keys(%data))) { # Personally, I prefer data sorted, # although you could leave out the sorts above, and following print $f1, "\n"; foreach my $f2 (sort(keys(%{$data{$f1}}))) { print $f2, "\n"; my $v4 = '|' if (defined($data{$f1}{$f2}{'data'} { $v4 .= join( ':', sort(@{$data{$f1}{$f2}{'data'}) ); } foreach my $v3 (sort(@{$data{$f1}{$f2}{'items'})) { print $v3, $v4, "\n"; } } } __DATA__ 100-233,MA,150:250 100-344,MA,350: 200-400,ER, 200-300,ER,576 100-250,MA,150 75-300,MA,350

    And now, a run, based on that data.

    If you do not wish duplicates in the last portion of the data, then you could do something like:

    if (defined($data{$f1}{$f2}{'data'} { my (%uniq); foreach (@{$data{$f1}{$f2}{'data'}) { $uniq{$_}++; } $v4 .= join( ':', sort(keys(%uniq)) ); }

    Hope that helps.

    Update: 19 Aug 2004

    Added <readmore></readmore> tags around the run/variable trace.

Re: Tricky Problem
by DamnDirtyApe (Curate) on Aug 19, 2004 at 16:39 UTC

    As far as managing the structure of the data goes, it looks like this should be sufficient:

    #! /usr/bin/perl -w use strict; use Data::Dumper; my %data; while ( <DATA> ) { chomp; my ( $begin, $end, $tag, @vals ) = split /[-,:]/; push @{$data{$begin}{$tag}{end_vals}}, $end; push @{$data{$begin}{$tag}{vals}}, @vals; } print Dumper \%data; __DATA__ 100-233,MA,150:250 100-344,MA,350: 200-400,ER, 200-300,ER,576

    I'll leave the formatting up to you. :-)


    _______________
    DamnDirtyApe
    Those who know that they are profound strive for clarity. Those who
    would like to seem profound to the crowd strive for obscurity.
                --Friedrich Nietzsche
Re: Tricky Problem
by ikegami (Patriarch) on Aug 19, 2004 at 16:53 UTC
    Also how do i find the number of lines in a file(text or any flatfile?)

    I didn't see an answer to this part of the question in the replies, so here goes: (Choose the one that fits best into your program.)

    sub get_num_lines_method1 { my ($file_name) = @_; my $num_lines = 0; local *FILE; open(FILE, $file_name); $num_lines++ while (<FILE>); close(FILE); return $num_lines; } sub get_num_lines_method2 { # Really same as get_num_lines_method1. my ($file_name) = @_; my $num_lines = 0; local *FILE; open(FILE, $file_name); while (<FILE>) { $num_lines++; } close(FILE); return $num_lines; } sub get_num_lines_method3 { # Loads the whole file into an array. my ($file_name) = @_; local *FILE; open(FILE, $file_name); my @file = <FILE>; close(FILE); return scalar(@file); } sub get_num_lines_method4 { # Loads the whole file into a scalar. my ($file_name) = @_; local *FILE; open(FILE, $file_name); local $/; my $file = <FILE>; close(FILE); return $file =~ tr/\n/\n/; } printf("Method 1: %d\n", get_num_lines_method1($0)); printf("Method 2: %d\n", get_num_lines_method2($0)); printf("Method 3: %d\n", get_num_lines_method3($0)); printf("Method 4: %d\n", get_num_lines_method4($0)); __END__ output: ======= Method 1: 62 Method 2: 62 Method 3: 62 Method 4: 62

    Update: None of the methods count the empty string between the last \n and the EOF as a line. Method 4 will not count a non-empty string between the last \n and the EOF as a line, although it should and could be modified to do so.

Re: Tricky Problem
by Jasper (Chaplain) on Aug 19, 2004 at 13:57 UTC
    What happens if you have:

    100-250,MA,150
    75-300,MA,350

    As others have commented, we have no idea what the logic behind your parsing is, so it's difficult to suggest anything. Although Cnn seems to have tried.
Re: Tricky Problem
by talexb (Chancellor) on Aug 19, 2004 at 17:20 UTC
      Also how do i find the number of lines in a file(text or any flatfile?)

    A Linux command line answer is wc -l; there's no Perl required.

    Alex / talexb / Toronto

    "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

      For that matter, in any of the solutions where a file is opened and they have looped through it, they can look at $. to find out the current line number (as long as they do it before they close the file). (See perlvar for further details.)

      (I also did not notice that part of the original posting earlier.)