Thread overview
Create array from range
Oct 09, 2021
Greg Strong
Oct 10, 2021
H. S. Teoh
Oct 10, 2021
jfondren
Oct 10, 2021
Ali Çehreli
October 09, 2021

This should be a simple question, but I'm having difficult finding an answer. How do I filter some elements of an array into a new array? The filter! function returns a range, but I can't seems to assign it to a new array. I get:

Cannot implicitly convert expression of type FilterResult!(__lambda10 ...

Nothing I try to construct a new array seems to work.

October 09, 2021
On Sat, Oct 09, 2021 at 11:58:14PM +0000, Greg Strong via Digitalmars-d-learn wrote:
> This should be a simple question, but I'm having difficult finding an answer.  How do I filter some elements of an array into a new array? The filter! function returns a range, but I can't seems to assign it to a new array.  I get:
> 
> Cannot implicitly convert expression of type FilterResult!(__lambda10 ...
> 
> Nothing I try to construct a new array seems to work.

You can use the .array function (from std.array) to create an array out
of the filtered range:

--------------
int[] myArray = [ ... ];
int[] filteredArray = myArray.filter!(e => ...).array;
--------------


T

-- 
Chance favours the prepared mind. -- Louis Pasteur
October 10, 2021

On Saturday, 9 October 2021 at 23:58:14 UTC, Greg Strong wrote:

>

This should be a simple question, but I'm having difficult finding an answer. How do I filter some elements of an array into a new array? The filter! function returns a range, but I can't seems to assign it to a new array. I get:

Cannot implicitly convert expression of type FilterResult!(__lambda10 ...

Nothing I try to construct a new array seems to work.

std.array.array does this:

https://dlang.org/phobos/std_array.html

and some other functions in that module are similar.

A value of output ranges like FilterResult is that you can decide how or whether to allocate an array of the results: you could allocate a new array with .array or you could consume the results as they come, or you could out pick a particular result, or you could populate a static array...

int example(R)(R range) @nogc {
    import std.range : take, enumerate;

    int[5] ints;

    foreach (size_t i, n; range.enumerate.take(ints.length))
        ints[i] = n;

    // just to do something with the array
    int sum;
    foreach (n; ints)
        sum += n;
    return sum;
}

unittest {
    import std.range : iota;
    import std.algorithm : filter;

    assert(20 == iota(100).filter!"a%2==0".example);
}
October 09, 2021
On 10/9/21 4:58 PM, Greg Strong wrote:
> How do I filter some elements of an array into a new array?  

This doesn't answer your specific question but std.algorithm.remove may be usable in some cases:

  https://dlang.org/phobos/std_algorithm_mutation.html#remove

If it matters, the following solution does not allocate new memory.

import std.stdio;
import std.algorithm;

void main() {
  auto arr = [ 1, 2, 3, 4, 5, 6, 7 ];

  // The default strategy is SwapStrategy.stable
  arr = arr.remove!(a => a % 2, SwapStrategy.unstable);

  writeln(arr);
}

The original array is modified. SwapStrategy.unstable will shuffle elements around. The program prints

[6, 2, 4]

Ali