.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Catmandu::Iterable 3pm" .TH Catmandu::Iterable 3pm "2019-01-29" "perl v5.28.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Catmandu::Iterable \- Base class for all iterable Catmandu classes .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 2 \& # Create an example Iterable using the Catmandu::Importer::Mock class \& my $it = Catmandu::Importer::Mock\->new(size => 10); \& \& my $array_ref = $it\->to_array; \& my $num = $it\->count; \& \& # Loop functions \& $it\->each(sub { print shift\->{n} }); \& \& my $item = $it\->first; \& \& $it\->rest \& \->each(sub { print shift\->{n} }); \& \& $it\->slice(3,2) \& \->each(sub { print shift\->{n} }); \& \& $it\->take(5) \& \->each(sub { print shift\->{n} }); \& \& $it\->group(5) \& \->each(sub { printf "group of %d items\en" , shift\->count}); \& \& $it\->tap(\e&logme)\->tap(\e&printme)\->tap(\e&mailme) \& \->each(sub { print shift\->{n} }); \& \& my $titles = $it\->pluck(\*(Aqtitle\*(Aq)\->to_array; \& \& # Select and loop \& my $item = $it\->detect(sub { shift\->{n} > 5 }); \& \& $it\->select(sub { shift\->{n} > 5}) \& \->each(sub { print shift\->{n} }); \& \& $it\->reject(sub { shift\->{n} > 5}) \& \->each(sub { print shift\->{n} }); \& \& # Boolean \& if ($it\->any(sub { shift\->{n} > 5}) { \& .. at least one n > 5 .. \& } \& \& if ($it\->many(sub { shift\->{n} > 5}) { \& .. at least two n > 5 .. \& } \& \& if ($it\->all(sub { shift\->{n} > 5}) { \& .. all n > 5 .. \& } \& \& # Modify and summary \& my $it2 = $it\->map(sub { shift\->{n} * 2 }); \& \& my $sum = $it2\->reduce(0,sub { \& my ($prev,$this) = @_; \& $prev + $this; \& }); \& \& my $it3 = $it\->group(2)\->invoke(\*(Aqto_array\*(Aq); \& \& # Calculate maximum of \*(Aqn\*(Aq field \& my $max = $it\->max(sub { \& shift\->{n}; \& }); \& \& # Calculate minimum of \*(Aqn\*(Aq field \& my $in = $it\->min(sub { \& shift\->{n}; \& }); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" The Catmandu::Iterable class provides many list methods to Iterators such as Importers and Exporters. Most of the methods are lazy if the underlying datastream supports it. Beware of idempotence: many iterators contain state information and calls will give different results on a second invocation. .SH "METHODS" .IX Header "METHODS" .SS "to_array" .IX Subsection "to_array" Return all the items in the Iterator as an \s-1ARRAY\s0 ref. .SS "count" .IX Subsection "count" Return the count of all the items in the Iterator. .PP \fI\s-1LOOPING\s0\fR .IX Subsection "LOOPING" .SS "each(\e&callback)" .IX Subsection "each(&callback)" For each item in the Iterator execute the callback function with the item as first argument. Returns the number of items in the Iterator. .SS "first" .IX Subsection "first" Return the first item from the Iterator. .SS "rest" .IX Subsection "rest" Returns an Iterator containing everything except the first item. .SS "slice(\s-1INDEX,LENGTH\s0)" .IX Subsection "slice(INDEX,LENGTH)" Returns an Iterator starting at the item at \s-1INDEX\s0 returning at most \s-1LENGTH\s0 results. .SS "take(\s-1NUM\s0)" .IX Subsection "take(NUM)" Returns an Iterator with the first \s-1NUM\s0 results. .SS "group(\s-1NUM\s0)" .IX Subsection "group(NUM)" Splitting the Iterator into \s-1NUM\s0 parts and returning an Iterator for each part. .SS "interleave(@iterators)" .IX Subsection "interleave(@iterators)" Returns an Iterator which returns the first item of each iterator then the second of each and so on. .SS "contains($data)" .IX Subsection "contains($data)" Alias for \f(CW\*(C`includes\*(C'\fR. .SS "includes($data)" .IX Subsection "includes($data)" return true if any item in the collection is deeply equal to \f(CW$data\fR. .SS "tap(\e&callback)" .IX Subsection "tap(&callback)" Returns a copy of the Iterator and executing callback on each item. This method works like the Unix tee command. Use this command to peek into an iterable while it is processing results. E.g. you are writing code to process an iterable and wrote something like: .PP .Vb 4 \& $it\->each(sub { \& # Very complicated routine \& ... \& }); .Ve .PP Now you would like to benchmark this piece of code (how fast are we processing). This can be done by tapping into the iterator and calling a 'benchmark' subroutine in your program that for instance counts the number of items divided by the execution time. .PP .Vb 4 \& $it\->tap(\e&benchmark)\->each(sub { \& # Very complicated routine \& ... \& }); \& \& sub benchmark { \& my $item = shift; \& $start ||= time; \& $count++; \& \& printf "%d recs/sec\en" , $count/(time \- $start + 1) if $count % 100 == 0; \& } .Ve .PP Note that the \f(CW\*(C`benchmark\*(C'\fR method already implements this common case. .SS "detect(\e&callback)" .IX Subsection "detect(&callback)" Returns the first item for which callback returns a true value. .SS "detect(qr/..../)" .IX Subsection "detect(qr/..../)" If the iterator contains \s-1STRING\s0 values, then return the first item which matches the regex. .ie n .SS "detect($key => $val)" .el .SS "detect($key => \f(CW$val\fP)" .IX Subsection "detect($key => $val)" If the iterator contains \s-1HASH\s0 values, then return the first item where the value of \&\f(CW$key\fR is equal to val. .SS "detect($key => qr/..../)" .IX Subsection "detect($key => qr/..../)" If the iterator contains \s-1HASH\s0 values, then return the first item where the value of \&\f(CW$key\fR matches the regex. .SS "detect($key => [$val, ...])" .IX Subsection "detect($key => [$val, ...])" If the iterator contains \s-1HASH\s0 values, then return the first item where the value of \&\f(CW$key\fR is equal to any of the vals given. .SS "pluck($key)" .IX Subsection "pluck($key)" Return an Iterator that only contains the values of the given \f(CW$key\fR. .SS "select(\e&callback)" .IX Subsection "select(&callback)" Returns an Iterator for each item for which callback returns a true value. .SS "select(qr/..../)" .IX Subsection "select(qr/..../)" If the iterator contains \s-1STRING\s0 values, then return each item which matches the regex. .ie n .SS "select($key => $val)" .el .SS "select($key => \f(CW$val\fP)" .IX Subsection "select($key => $val)" If the iterator contains \s-1HASH\s0 values, then return each item where the value of \&\f(CW$key\fR is equal to val. .SS "select($key => qr/..../)" .IX Subsection "select($key => qr/..../)" If the iterator contains \s-1HASH\s0 values, then return each item where the value of \f(CW$key\fR matches the regex. .SS "select($key => [$val, ...])" .IX Subsection "select($key => [$val, ...])" If the iterator contains \s-1HASH\s0 values, then return each item where the value of \&\f(CW$key\fR is equal to any of the vals given. .SS "grep( ... )" .IX Subsection "grep( ... )" Alias for \f(CW\*(C`select( ... )\*(C'\fR. .SS "reject(\e&callback)" .IX Subsection "reject(&callback)" Returns an Iterator for each item for which callback returns a false value. .SS "reject(qr/..../)" .IX Subsection "reject(qr/..../)" If the iterator contains \s-1STRING\s0 values, then reject every item except those matching the regex. .SS "reject($key => qr/..../)" .IX Subsection "reject($key => qr/..../)" If the iterator contains \s-1HASH\s0 values, then reject every item for where the value of \f(CW$key\fR \&\s-1DOESN\s0'T match the regex. .ie n .SS "reject($key => $val)" .el .SS "reject($key => \f(CW$val\fP)" .IX Subsection "reject($key => $val)" If the iterator contains \s-1HASH\s0 values, then return each item where the value of \&\f(CW$key\fR is \s-1NOT\s0 equal to val. .SS "reject($key => [$val, ...])" .IX Subsection "reject($key => [$val, ...])" If the iterator contains \s-1HASH\s0 values, then return each item where the value of \&\f(CW$key\fR is \s-1NOT\s0 equal to any of the vals given. .SS "sorted" .IX Subsection "sorted" Returns an Iterator with items sorted lexically. Note that sorting requires memory because all items are buffered in a Catmandu::ArrayIterator. .SS "sorted(\e&callback)" .IX Subsection "sorted(&callback)" Returns an Iterator with items sorted by a callback. The callback is expected to returns an integer less than, equal to, or greater than \f(CW0\fR. The following code snippets result in the equal arrays: .PP .Vb 2 \& $iterator\->sorted(\e&callback)\->to_array \& [ sort \e&callback @{ $iterator\->to_array } ] .Ve .SS "sorted($key)" .IX Subsection "sorted($key)" Returns an Iterator with items lexically sorted by a key. This is equivalent to sorting with the following callback: .PP .Vb 1 \& $iterator\->sorted(sub { $_[0]\->{$key} cmp $_[1]\->{$key} }) .Ve .PP \fI\s-1EXTERNAL ITERATOR\s0\fR .IX Subsection "EXTERNAL ITERATOR" .PP Catmandu::Iterable behaves like an internal iterator. \f(CW\*(C`next\*(C'\fR and \f(CW\*(C`rewind\*(C'\fR allow you to use it like an external iterator. .SS "next" .IX Subsection "next" Each call to \f(CW\*(C`next\*(C'\fR will return the next item until the iterator is exhausted, then it will keep returning \f(CW\*(C`undef\*(C'\fR. .PP .Vb 3 \& while (my $data = $it\->next) { \& # do stuff \& } \& \& $it\->next; # returns undef .Ve .SS "rewind" .IX Subsection "rewind" Rewind the external iterator to the first item. .PP .Vb 5 \& $it\->next; # => {n => 1} \& $it\->next; # => {n => 2} \& $it\->next; # => {n => 3} \& $it\->rewind \& $it\->next; # => {n => 1} .Ve .PP Note the the iterator must support this behavior. Many importers are not rewindable. .PP \fI\s-1BOOLEAN FUNCTIONS\s0\fR .IX Subsection "BOOLEAN FUNCTIONS" .SS "any(\e&callback)" .IX Subsection "any(&callback)" Returns true if at least one item generates a true value when executing callback. .SS "many(\e&callback)" .IX Subsection "many(&callback)" Alias for \f(CW\*(C`many\*(C'\fR. .SS "many(\e&callback)" .IX Subsection "many(&callback)" Returns true if at least two items generate a true value when executing callback. .SS "all(\e&callback)" .IX Subsection "all(&callback)" Returns true if all the items generate a true value when executing callback. .PP \fI\s-1MAP & REDUCE\s0\fR .IX Subsection "MAP & REDUCE" .SS "map(\e&callback)" .IX Subsection "map(&callback)" Returns a new Iterator containing for each item the result of the callback. If the callback returns multiple or no items, the resulting iterator will grow or shrink. .SS "reduce([\s-1START\s0],\e&callback)" .IX Subsection "reduce([START],&callback)" Alias for \f(CW\*(C`reduce\*(C'\fR. .SS "reduce([\s-1START\s0],\e&callback)" .IX Subsection "reduce([START],&callback)" For each item in the Iterator execute &callback($prev,$item) where \f(CW$prev\fR is the option \s-1START\s0 value or the result of the previous call to callback. Returns the final result of the callback function. .SS "invoke(\s-1NAME\s0)" .IX Subsection "invoke(NAME)" Returns an interator were the method \s-1NAME\s0 is called on every object in the iterable. This is a shortcut for \f(CW$it\fR\->map(sub { \f(CW$_\fR[0]\->\s-1NAME\s0 }). .SS "\fBmax()\fP" .IX Subsection "max()" Returns the maximum of an iterator containing only numbers. .SS "max(\e&callback)" .IX Subsection "max(&callback)" Returns the maximum of the numbers returned by executing callback. .SS "\fBmin()\fP" .IX Subsection "min()" Returns the minimum of an iterator containing only numbers. .SS "min(\e&callback)" .IX Subsection "min(&callback)" Returns the minimum of the numbers returned by executing callback. .SS "\fBbenchmark()\fP" .IX Subsection "benchmark()" Prints the number of records processed per second to \s-1STDERR.\s0 .SS "format(cols => ['key', ...], col_sep => ' | ', header => 1|0)" .IX Subsection "format(cols => ['key', ...], col_sep => ' | ', header => 1|0)" Print the iterator data formatted as a spreadsheet like table. Note that this method will load the whole dataset in memory to calculate column widths. See also Catmandu::Exporter::Table for a more elaborated method of printing iterators in tabular form. .SS "stop_if(\e&callback)" .IX Subsection "stop_if(&callback)" Returns a new iterator thats stops processing if the callback returns false. .PP .Vb 10 \& # stop after encountering 3 frobnitzes \& my $frobnitzes = 0; \& $iterator\->stop_if(sub { \& my $rec = shift; \& $frobnitzes++ if $rec\->{title} =~ /frobnitz/; \& $frobnitzes > 3; \& })\->each(sub { \& my $rec = shift; \& ... \& }); .Ve .SS "run" .IX Subsection "run" Simply invokes the iterator and returns 1 if any records were processed, 0 otherwise. .PP .Vb 7 \& $it = $it\->tap(sub { \& # do something \& }); \& $it = $it\->tap(sub { \& # do another thing \& }); \& $it\->run \& \& print \*(Aqnot empty\*(Aq if $it\->run; .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" Catmandu::Iterator.