perl - Sorting multidimensional array with exceptions -


i have file contains time , data. need sort array time, there 2 snags: if time 23:59:59:999 or null, needs stay in relation else. i've taken in file , placed in array of arrays.

for example:

data1   10:25:34.001    data2 data1   10:25:34.002    data2 data1   10:25:34.005    data2 data1   null            data2 data1   null            data2 data1   null            data2 data1   10:25:34.006    data2 data1   10:25:34.007    data2 data1   10:25:34.008    data2 data1   23:59:59:999    data2 data1   23:59:59:999    data2 data1   10:25:34.003    data2 data1   10:25:34.004    data2 data1   10:25:34.010    data2 data1   10:25:34.011    data2 

should become:

data1   10:25:34.001    data2 data1   10:25:34.002    data2 data1   10:25:34.003    data2 data1   10:25:34.004    data2 data1   10:25:34.005    data2 data1   null            data2 data1   null            data2 data1   null            data2 data1   10:25:34.006    data2 data1   10:25:34.007    data2 data1   10:25:34.008    data2 data1   23:59:59:999    data2 data1   23:59:59:999    data2 data1   10:25:34.010    data2 data1   10:25:34.011    data2 

what have done sort them separate "blocks" (time, null times etc) when dump array of data looks like:

(     [         [           "data1",           "10:25:34.001",           "data2",         ],         [            "data1",           "10:25:34.002",           "data2",         ],         [            "data1",           "10:25:34.005",           "data2",         ],     ],     [         [            "data1",           "null",           "data2",         ],         [            "data1",           "null",           "data2",         ],         [            "data1",           "null",           "data2",         ],     ],     [         [            "data1",           "10:25:34.006",           "data2",         ],         [            "data1",           "10:25:34.007",           "data2",         ],         [            "data1",           "10:25:34.008",           "data2",         ],     ],     [         [           "data1",           "23:59:59:999",           "data2",         ],         [            "data1",           "23:59:59:999",           "data2",         ],     ],     [         [            "data1",           "10:25:34.003",           "data2",         ],         [            "data1",           "10:25:34.004",           "data2",         ],         [            "data1",           "10:25:34.010",           "data2",         ],         [            "data1",           "10:25:34.011",           "data2",         ],     ] ) 

my idea find maximum value "first" block , ignore "null" , "23:59:59.999" blocks, , push values in remaining block larger maximum value of "first" block.

i'm having difficulty moving times between separate blocks , sort it, , wondering if had advise on how (or if there better way of sorting structure i've got far) ?

to achieve want, cannot sort original data structure. need transform rows relative positions want preserve attached preceding elements.

here's updated version bit better first implementation posted (see edit history if curious):

#!/usr/bin/env perl  use strict; use warnings;  @data = [ [ split ' ', scalar <data> ] ];  while (my $row = <data>) {     next unless $row =~ /\s/;     @x = split ' ', $row;     if (($x[1] eq 'null') or ($x[1] eq '23:59:59:999')) {         push @{ $data[-1] }, \@x;         next;     }     push @data, [ \@x ]; }  @data = map @$_, sort { $a->[0][1] cmp $b->[0][1] } @data;  print "@$_\n" @data;  __data__ data1   10:25:34.001    data2 data1   10:25:34.002    data2 data1   10:25:34.005    data2 data1   null            data2 data1   null            data2 data1   null            data2 data1   10:25:34.006    data2 data1   10:25:34.007    data2 data1   10:25:34.008    data2 data1   23:59:59:999    data2 data1   23:59:59:999    data2 data1   10:25:34.003    data2 data1   10:25:34.004    data2 data1   10:25:34.010    data2 data1   10:25:34.011    data2 

output:

data1 10:25:34.001 data2 data1 10:25:34.002 data2 data1 10:25:34.003 data2 data1 10:25:34.004 data2 data1 10:25:34.005 data2 data1 null data2 data1 null data2 data1 null data2 data1 10:25:34.006 data2 data1 10:25:34.007 data2 data1 10:25:34.008 data2 data1 23:59:59:999 data2 data1 23:59:59:999 data2 data1 10:25:34.010 data2 data1 10:25:34.011 data2

this assume first line of data not null or midnight event. can use sentry element if first row of data may contain null or midnight event:

#!/usr/bin/env perl  use strict; use warnings;  @data = [ [ undef, undef, undef ] ];  while (my $row = <data>) {     next unless $row =~ /\s/;     @x = split ' ', $row;     if (($x[1] eq 'null') or ($x[1] eq '23:59:59:999')) {         push @{ $data[-1] }, \@x;         next;     }     push @data, [ \@x ]; }  @data = map @$_, sort {     $a->[0][1] or return -1;     $b->[0][1] or return  1;     $a->[0][1] cmp $b->[0][1] } @data;  shift @data; print "@$_\n" @data; 

we make sure sentry element sorts before other element, , remove before doing further data.


Comments

Popular posts from this blog

yii2 - Yii 2 Running a Cron in the basic template -

asp.net - 'System.Web.HttpContext' does not contain a definition for 'GetOwinContext' Mystery -

mercurial graft feature, can it copy? -