in reply to grepping the location of a value from a datastructure
If you want to trundle through an arbitrarily deep reference tree with grep-like syntax, it's actually fairly easy to implement:
use 5.016; # For __SUB__, or pre-declare $grep and use $grep->() s +yntax sub ref_grep(&$) { my ($wanted, $ref) = @_; my $seen = {}; # Refs we've already seen (avoid circular refs) my @found; # Result list my $grep = sub { my ($ref, $path) = @_; return if ref $ref and $seen->{$ref}++; { $_ = $ref; push @found, $path if $wanted->() } for (ref $ref) { when ('HASH') { __SUB__->($ref->{$_}, $path."->{$_}") for sort key +s $ref; } when ('ARRAY') { __SUB__->($ref->[$_], $path."->[$_]") for sort key +s $ref; } } }; $grep->($ref, ''); return @found; }
Invocation is just like grep:
say "Found value2: \$hash$_" for ref_grep { $_ eq 'value2' } $hash;It's not limited to scalars, either; the BLOCK can perform any test it likes.
Of course, this is not without limitations. Support for nested objects, tests based on the path itself, pruning, etc., would take more work, and I'd certainly not try much harder to re-invent this wheel. What I'm saying is, take this as a starting point.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: grepping the location of a value from a datastructure
by rastoboy (Monk) on Aug 07, 2013 at 17:34 UTC |