### ----------------------------------------------------
### -- List::MoreUtils
### -- Licenses: Artistic-2.0
### -- Authors: Elizabeth Mattijsen
### -- File: README.md
### ----------------------------------------------------
### -- Chunk 2 of 2
 = <alpha beta cicero delta>;
    my $found = bsearch Scalar, { $_ cmp "cicero" }, @list;   # True
    my $found = bsearch Scalar, { $_ cmp "effort" }, @list;   # False

### bsearchidx BLOCK, LIST

### bsearch_index BLOCK, LIST

Performs a binary search on LIST which must be a sorted list of values. BLOCK receives each element in turn and must return a negative value if the element is smaller, a positive value if it is bigger and zero if it matches.

Returns the index of found element, otherwise `-1`.

    my @list  = <alpha beta cicero delta>;
    my $found = bsearchidx { $_ cmp "cicero" }, @list;   # 2
    my $found = bsearchidx { $_ cmp "effort" }, @list;   # -1

`bsearch_index` is an alias for `bsearchidx`.

### lower_bound BLOCK, LIST

Returns the index of the first element in LIST which does not compare *less than val*. Technically it's the first element in LIST which does not return a value below zero when passed to BLOCK.

    my @ids = 1, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6;
    my $lb = lower_bound { $_ <=> 2 }, @ids; # 1
    my $lb = lower_bound { $_ <=> 4 }, @ids; # 9

### upper_bound BLOCK, LIST

Returns the index of the first element in LIST which does not compare *greater than val*. Technically it's the first element in LIST which does not return a value below or equal to zero when passed to BLOCK.

    my @ids = 1, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6;
    my $ub = upper_bound { $_ <=> 2 }, @ids; # 3
    my $ub = upper_bound { $_ <=> 4 }, @ids; # 13

### equal_range BLOCK, LIST

Returns a list of indices containing the `lower_bound` and the `upper_bound` of given BLOCK and LIST.

    my @ids = 1, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6;
    my $er = equal_range { $_ <=> 2 }, @ids; # (1,3)
    my $er = equal_range { $_ <=> 4 }, @ids; # (9,13)

Operations on sorted Lists
--------------------------

### binsert BLOCK, ITEM, LIST

### bsearch_insert BLOCK, ITEM, LIST

Performs a binary search on LIST which must be a sorted list of values. BLOCK must return a negative value if the current element (passed as a parameter to the BLOCK) is smaller, a positive value if it is bigger and zero if it matches.

ITEM is inserted at the index where the ITEM should be placed (based on above search). That means, it's inserted before the next bigger element.

    my @l = 2,3,5,7;
    binsert { $_ <=> 4 },  4, @l; # @l = (2,3,4,5,7)
    binsert { $_ <=> 6 }, 42, @l; # @l = (2,3,4,5,42,7)

You take care that the inserted element matches the compare result.

`bsearch_insert` is an alias for `binsert`.

### bremove BLOCK, LIST

### bsearch_remove BLOCK, LIST

Performs a binary search on LIST which must be a sorted list of values. BLOCK must return a negative value if the current element (passed as a parameter to the BLOCK) is smaller, a positive value if it is bigger and zero if it matches.

The item at the found position is removed and returned.

    my @l = 2,3,4,5,7;
    bremove { $_ <=> 4 }, @l; # @l = (2,3,5,7);

`bsearch_remove` is an alias for `bremove`.

Counting and calculation
------------------------

### true BLOCK, LIST

Counts the number of elements in LIST for which the criterion in BLOCK is true. Passes each item in LIST to BLOCK in turn:

    printf "%i item(s) are defined", true { defined($_) }, @list;

#### Idiomatic Raku ways

    print "@list.grep(*.defined).elems() item(s) are defined";

### false BLOCK, LIST

Counts the number of elements in LIST for which the criterion in BLOCK is false. Passes each item in LIST to BLOCK in turn:

    printf "%i item(s) are not defined", false { defined($_) }, @list;

#### Idiomatic Raku ways

    print "@list.grep(!*.defined).elems() item(s) are not defined";

### reduce_0 BLOCK, LIST

Reduce LIST by calling BLOCK in scalar context for each element of LIST. The first parameter contains the progressional result and is initialized with **0**. The second parameter contains the currently being processed element of LIST.

    my $reduced = reduce_0 -> $a, $b { $a + $b }, @list;

In the Perl version, `$_` is also set to the index of the element being processed. This is not the case in the Raku version for various reasons. Should you need the index value in your calculation, you can post-increment the anonymous state variable instead: `$++`:

    my $reduced = reduce_0 -> $a, $b { dd $++ }, @list; # 0 1 2 3 4 5 ...

The idea behind reduce_0 is **summation** (addition of a sequence of numbers).

### reduce_1 BLOCK, LIST

Reduce LIST by calling BLOCK in scalar context for each element of LIST. The first parameter contains the progressional result and is initialized with **1**. The second parameter contains the currently being processed element of LIST.

    my $reduced = reduce_1 -> $a, $b { $a * $b }, @list;

In the Perl version, `$_` is also set to the index of the element being processed. This is not the case in the Raku version for various reasons. Should you need the index value in your calculation, you can post-increment the anonymous state variable instead: `$++`:

    my $reduced = reduce_1 -> $a, $b { dd $++ }, @list; # 0 1 2 3 4 5 ...

The idea behind reduce_1 is **product** of a sequence of numbers.

### reduce_u BLOCK, LIST

Reduce LIST by calling BLOCK in scalar context for each element of LIST. The first parameter contains the progressional result and is initialized with **Any**. The second parameter contains the currently being processed element of LIST.

    my $reduced = reduce_u -> $a, $b { $a.push($b) }, @list;

In the Perl version, `$_` is also set to the index of the element being processed. This is not the case in the Raku version for various reasons. Should you need the index value in your calculation, you can post-increment the anonymous state variable instead: `$++`:

    my $reduced = reduce_u -> $a, $b { dd $++ }, @list; # 0 1 2 3 4 5 ...

The idea behind reduce_u is to produce a list of numbers.

### minmax LIST

Calculates the minimum and maximum of LIST and returns a two element list with the first element being the minimum and the second the maximum. Returns the empty list if LIST was empty.

    my ($min,$max) = minmax (43,66,77,23,780); # (23,780)

#### Idiomatic Raku ways

    my $range = <43,66,77,23,780>.minmax( +* );
    my $range = (43,66,77,23,780).minmax;   # auto-numerically compares

### minmaxstr LIST

Computes the minimum and maximum of LIST using string compare and returns a two element list with the first element being the minimum and the second the maximum. Returns the empty list if LIST was empty.

    my ($min,$max) = minmaxstr <foo bar baz zippo>; # <bar zippo>

#### Idiomatic Raku ways

    my $range = (43,66,77,23,780).minmax( ~* );
    my $range = <foo bar baz zippo>.minmax;  # auto-string compares

SEE ALSO
========

[List::Util](List::Util), [List::AllUtils](List::AllUtils), [List::UtilsBy](List::UtilsBy)

THANKS
======

Thanks to all of the individuals who have contributed to the Perl version of this module.

AUTHOR
======

Elizabeth Mattijsen <liz@raku.rocks>

If you like this module, or what I’m doing more generally, committing to a [small sponsorship](https://github.com/sponsors/lizmat/) would mean a great deal to me!

Source can be located at: https://github.com/lizmat/List-MoreUtils . Comments and Pull Requests are welcome.

COPYRIGHT AND LICENSE
=====================

Copyright 2018, 2019, 2020, 2021, 2023 Elizabeth Mattijsen

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.

Re-imagined from the Perl version as part of the CPAN Butterfly Plan. Perl version originally developed by Tassilo von Parseval, subsequently maintained by Adam Kennedy and Jens Rehsack.



