www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - specifying an auto array type

reply Jay Norwood <jayn prismnet.com> writes:
This is getting kind of a long example, but I'm really only 
interested in the last 4 or 5 lines. This works as desired, 
creating the array of tuples, but I'm wondering if there is a way 
to have the Tuple array defined as auto instead of having to 
specify the types.  I tried using .array() at the end of the last 
samples.each!, but couldn't find an implementation that worked.

Yes, I know, some of these imports aren't required (yet).

import std.stdio;
import std.algorithm;
import std.conv;
import std.range;
import std.typecons;
import std.parallelism;
import std.array;

struct S { ulong a; ulong b; ulong c; ulong d; double e; ulong f;}
ulong f1(ref S s) { with(s){return a+b;}}
double f2(ref S s) { with(s){return (c+d)/e;}}
double f3(ref S s) { with(s){return (c+f)/e;}}

int main()
{

	S[10] samples;
	// initialize some values
	foreach ( int i, ref s; samples){
		int j=i+1;
		with (s){
			a=j; b=j*2; c=j*3; d=j*4; e=j*10; f=j*5;
		}
	}

	// apply several functions on each  sample
	samples.each!((int i, ref 
a)=>tuple!("sample","f1","f2","f3")(i,f1(a),f2(a),f3(a)).writeln());

	// output the function results to an array of tuples
	Tuple!(int, ulong, double, double)[] arr;

	samples.each!((int i, ref a)=> arr ~= 
tuple!("sample","f1","f2","f3")(i,f1(a),f2(a),f3(a)));
	writeln(arr);
	return 0;
}
Dec 26 2015
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 12/26/2015 09:45 PM, Jay Norwood wrote:

 This is getting kind of a long example,
There are issues with that code that make it hard for me to guess the intent.
 a way to have the Tuple array defined as auto instead of having to 
specify
 the types.  I tried using .array() at the end of the last 
samples.each!, but
 couldn't find an implementation that worked.
It looks like you need map(), not each(): import std.algorithm; import std.typecons; import std.array; void main() { auto a = [ 1, 2 ]; auto arr = a.map!(e => tuple(2 * e, e * e)).array; static assert(is(typeof(arr) == Tuple!(int, int)[])); } Ali
Dec 26 2015
parent reply Jay Norwood <jayn prismnet.com> writes:
On Sunday, 27 December 2015 at 07:40:55 UTC, Ali Çehreli wrote:
 It looks like you need map(), not each():

 import std.algorithm;
 import std.typecons;
 import std.array;

 void main() {
     auto a = [ 1, 2 ];
     auto arr = a.map!(e => tuple(2 * e, e * e)).array;

     static assert(is(typeof(arr) == Tuple!(int, int)[]));
 }

 Ali
ok, thanks. This does work, using the uint i ahead of the map statement. uint i=0; auto arr = samples[].map!(a => tuple!("sample","f1","f2","f3")(i++,f1(a),f2(a),f3(a))).array; writeln(arr); ===== output Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(0, 3, 0.7, 0.8) Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(1, 6, 0.7, 0.8) Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(2, 9, 0.7, 0.8) Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(3, 12, 0.7, 0.8) Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(4, 15, 0.7, 0.8) Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(5, 18, 0.7, 0.8) Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(6, 21, 0.7, 0.8) Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(7, 24, 0.7, 0.8) Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(8, 27, 0.7, 0.8) Tuple!(int, "sample", ulong, "f1", double, "f2", double, "f3")(9, 30, 0.7, 0.8) ============= However, I was trying to use each!, with the intention of then moving to parallel processing by samples blocks. My guess is this would be more efficient than using parallel map or amap, which would parallel process by function application, if I understand correctly. It isn't clear to me from the examples if something like below can be rewritten to use the chained calls. foreach(i, ref elem; taskPool.parallel(samples, 100))
Dec 27 2015
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 12/27/2015 08:42 AM, Jay Norwood wrote:

 However, I was trying to use each!, with the intention of then moving to
 parallel processing by samples blocks. My guess is this would be more
 efficient than using parallel map or amap, which would parallel process
 by function application, if I understand correctly.
There is also taskPool.asyncBuf but it made your code on the other thread with apply_metrics() even slower.
 It isn't clear to me from the examples if something like below can be
 rewritten to use the chained calls.

 foreach(i, ref elem; taskPool.parallel(samples, 100))
parallel() returns struct ParallelForeach, which is not an InputRange. That limits its usefulness. However, each() seems to work with types that provide opApply() (which ParallelForeach does) and the following works (in some cases): some.range.chain.parallel.each!(/* ... */); Ali
Dec 27 2015