Thread overview
confused with data types
Feb 17, 2018
thorstein
Feb 17, 2018
JN
Feb 17, 2018
Adam D. Ruppe
Feb 17, 2018
arturg
Feb 18, 2018
thorstein
Feb 18, 2018
thorstein
Feb 18, 2018
arturg
Feb 18, 2018
thorstein
February 17, 2018
Hello,

This was my goal:
-----------------
public double[][] skalar_m_2d(double[][] array, double skalar)
{
  return array.map!(b => b[].map!(c => c * skalar));
}

!!! But: return value is not double!

Type check for return value:
----------------------------
a = array.map!(b => b[].map!(c => c * skalar))
writeln(typeof(a).stringof); //-> MapResult!("__lambda4, double[][])

a = array.map!(b => b[].map!(c => c * skalar))[1];
writeln(typeof(a).stringof); //-> MapResult!("__lambda2, double[])

How can I get the result as double[][] ???

Thanks, thorstein
February 17, 2018
On Saturday, 17 February 2018 at 16:12:48 UTC, thorstein wrote:
> Hello,
>
> This was my goal:
> -----------------
> public double[][] skalar_m_2d(double[][] array, double skalar)
> {
>   return array.map!(b => b[].map!(c => c * skalar));
> }
>
> !!! But: return value is not double!
>
> Type check for return value:
> ----------------------------
> a = array.map!(b => b[].map!(c => c * skalar))
> writeln(typeof(a).stringof); //-> MapResult!("__lambda4, double[][])
>
> a = array.map!(b => b[].map!(c => c * skalar))[1];
> writeln(typeof(a).stringof); //-> MapResult!("__lambda2, double[])
>
> How can I get the result as double[][] ???
>
> Thanks, thorstein

I'm no expert, but importing std.array and doing a.array() should work.
February 17, 2018
On Saturday, 17 February 2018 at 16:12:48 UTC, thorstein wrote:
> public double[][] skalar_m_2d(double[][] array, double skalar)
> {
>   return array.map!(b => b[].map!(c => c * skalar));
> }

It'd probably be better to just do that in-place...

foreach(row; array)
  row[] *= skalar;
return array;

Note that'd overwrite the existing data though. But the compiler could more aggressively optimize that than the individual maps.

> How can I get the result as double[][] ???


But if you do need the double[][] type exactly as well as a new copy instead of editing the one you have, you can:

static import std.array;
return std.array.array(array.map!(b => std.array.array(b[].map!(c => c * skalar))));


The std.array.array function copies the return value of functions like `map` into a new array. It is called twice here because double[][] is an array of arrays.

(the word "array" is used way too much there lol)


The reason map doesn't do this automatically btw is because copying the arrays can be somewhat expensive, so it doesn't force you to do work you don't often need.
February 17, 2018
double[][] skalar_m_2d(double[][] arr, double skalar)
{
    import std.algorithm;
    // return arr.map(a=> a[] *= skalar).array;
    arr.each!((ref a) => a[] *= skalar));
    return arr;
}

February 18, 2018
Thank you for the very informative answers showing different gears in D!

However, there are still some details I'm struggling with:

Assume some calculations on a very big numeric array 'double[][][] arr'.
Now we could choose 1 out of 3 different implementations:
// Solution 1
foreach(row; arr)
{ foreach(col; row)
  { col[] *= skalar;
  }
}
return arr;

// Solution 2
import std.array;
return array(arr.map!(b => array(b[].map!(c => array(c[].map!(d => d * skalar))))));

// Solution 3
import std.algorithm;
arr.each!(a => a[].each!(b => b[] *= skalar));
return arr;

Q#1:
Does the compiler optimizes all solutions equally strong or does it prefer implementations like solution 1?

Q#2:
Solution 2 is a 1-liner but a bit harder to read. Why reducing solution 3 to:
return arr.each!(a => a[].each!(b => b[] *= skalar));
gives a compile error? I do writeln() the function result.

Q#3:
If I can:
static import std.array;
return std.array.array(arr.map!(b => std.array.array(b[].map!(c =>...

How would I apply a similar version with 'static import std.algorithm' to solution 3?
static import std.algorithm;
std.algorithm.arr.each!(a => a[]... //does obviously not work

Thanks, thorstein
February 18, 2018
On Sunday, 18 February 2018 at 12:51:04 UTC, thorstein wrote:
> Thank you for the very informative answers showing different gears in D!
>
> However, there are still some details I'm struggling with:
>
> Assume some calculations on a very big numeric array 'double[][][] arr'.
> Now we could choose 1 out of 3 different implementations:
> // Solution 1
> foreach(row; arr)
> { foreach(col; row)
>   { col[] *= skalar;
>   }
> }
> return arr;
>
> // Solution 2
> import std.array;
> return array(arr.map!(b => array(b[].map!(c => array(c[].map!(d => d * skalar))))));
>
> // Solution 3
> import std.algorithm;
> arr.each!(a => a[].each!(b => b[] *= skalar));
> return arr;
>
> Q#1:
> Does the compiler optimizes all solutions equally strong or does it prefer implementations like solution 1?
>
> Q#2:
> Solution 2 is a 1-liner but a bit harder to read. Why reducing solution 3 to:
> return arr.each!(a => a[].each!(b => b[] *= skalar));
> gives a compile error? I do writeln() the function result.
>
> Q#3:
> If I can:
> static import std.array;
> return std.array.array(arr.map!(b => std.array.array(b[].map!(c =>...
>
> How would I apply a similar version with 'static import std.algorithm' to solution 3?
> static import std.algorithm;
> std.algorithm.arr.each!(a => a[]... //does obviously not work
>
> Thanks, thorstein

Sorry, Solution 2 should be:

import std.array;
return array(arr.map!(b => array(b[].map!(c => c[] *= skalar))));

and is as readable as Solution 3. However, Q#2 still remains.
February 18, 2018
On Sunday, 18 February 2018 at 13:08:09 UTC, thorstein wrote:
> On Sunday, 18 February 2018 at 12:51:04 UTC, thorstein wrote:
>> // Solution 1
>> foreach(row; arr)
>> { foreach(col; row)
>>   { col[] *= skalar;
>>   }
>> }
>> return arr;
>>
>> // Solution 2
>> import std.array;
>> return array(arr.map!(b => array(b[].map!(c => array(c[].map!(d => d * skalar))))));
>>
>> // Solution 3
>> import std.algorithm;
>> arr.each!(a => a[].each!(b => b[] *= skalar));
>> return arr;
>>
>> Q#1:
>> Does the compiler optimizes all solutions equally strong or does it prefer implementations like solution 1?
>>
>> Q#2:
>> Solution 2 is a 1-liner but a bit harder to read. Why reducing solution 3 to:
>> return arr.each!(a => a[].each!(b => b[] *= skalar));
>> gives a compile error? I do writeln() the function result.
>>
>> Q#3:
>> If I can:
>> static import std.array;
>> return std.array.array(arr.map!(b => std.array.array(b[].map!(c =>...
>>
>> How would I apply a similar version with 'static import std.algorithm' to solution 3?
>> static import std.algorithm;
>> std.algorithm.arr.each!(a => a[]... //does obviously not work
>>
>> Thanks, thorstein
>
> Sorry, Solution 2 should be:
>
> import std.array;
> return array(arr.map!(b => array(b[].map!(c => c[] *= skalar))));
>
> and is as readable as Solution 3. However, Q#2 still remains.

Q#1: i would guess solution 1 would be the fastest and solution 2 the slowest.
Q#2: you get a error because each returns void.
Q#3: you cant use ufcs with static imports, you have to call the function normaly:
    static import algo = std.algorithm;
    algo.each!((a) => algo.each!((b) => b[] *= skalar)(a))(arr);

February 18, 2018
Thanks for all the insights :)