function _do_reduce($path, $ctx) { // my $indent = ' ' x $ctx->{depth}; $indent = str_repeat(' ', $ctx['depth']); // my $debug = $ctx->{debug}; $debug = $ctx['debug']; // my $ra = Regexp::Assemble->new(chomp=>0); $ra = new Regexp_Assemble(array('chomp' => 0)); // $ra->debug($debug); $ra->__debug = $debug; //$ra->__debug = 255; // $debug and print "# $indent| do @{[_dump($path)]}\n"; if ($debug) { echo "# {$indent}| do " . $this->_dump($path) . "\n"; } // $ra->_insertr( $_ ) for // # When nodes come into the picture, we have to be careful // # about how we insert the paths into the assembly. // # Paths with nodes first, then closest node to front // # then shortest path. Merely because if we can control // # order in which paths containing nodes get inserted, // # then we can make a couple of assumptions that simplify // # the code in _insert_node. // sort { // scalar(grep {ref($_) eq 'HASH'} @$a) // <=> scalar(grep {ref($_) eq 'HASH'} @$b) // || // _node_offset($b) <=> _node_offset($a) // || // scalar @$a <=> scalar @$b // } // @$path // ; $self = $this; //php5.4からは thisは暗黙なのだが・・ php5.3で動かしたいので、一度代入して自分で束縛する. $_temp_path = $this->_perl_sort(function ($a, $b) use($self) { $scalar_count_a = count($self->_perl_grep(function ($_) { return is_array($_); }, $a)); $scalar_count_b = count($self->_perl_grep(function ($_) { return is_array($_); }, $b)); if ($scalar_count_a > $scalar_count_b) { return 1; } else { if ($scalar_count_a < $scalar_count_b) { return -1; } } $temp_b = $self->_node_offset($b); $temp_a = $self->_node_offset($a); if ($temp_b > $temp_a) { return 1; } else { if ($temp_b < $temp_a) { return -1; } } $temp_a = count($a); $temp_b = count($b); if ($temp_a > $temp_b) { return 1; } else { if ($temp_a < $temp_b) { return -1; } } //挙動を見ていると辞書順な気がする・・・ return strcmp(is_array($a) ? json_encode($a) : $a, is_array($b) ? json_encode($b) : $b); // return 0; }, $path); foreach ($_temp_path as $_) { $ra->_insertr($_); } // $path = $ra->_path; $path = $ra->__path; // my $common = []; $common = array(); // push @$common, shift @$path while( ref($path->[0]) ne 'HASH' ); //これでいいんかな? while (count($path) > 0 && !is_array($path[0])) { // $common = $this->_perl_push2($common, array_shift($path)); $_temp_node = array_shift($path); if (is_array($_temp_node)) { $common = array_merge($common, $_temp_node); } else { $common[] = $_temp_node; } } // my $tail = scalar( @$path ) > 1 ? [@$path] : $path->[0]; $tail = count($path) > 1 ? $path : $path[0]; // $debug and print "# $indent| _do_reduce common={[_dump($common)]} tail=@{[_dump($tail)]}\n"; if ($debug) { echo "# {$indent}| _do_reduce common=" . $this->_dump($common) . " tail=" . $this->_dump($tail) . "\n"; } // return ($common, $tail); return array($common, $tail); //} }