<br><br><div class="gmail_quote">On Tue, Mar 16, 2010 at 17:35, Jesse Phillips <span dir="ltr">&lt;<a href="mailto:jessekphillips%2BD@gmail.com">jessekphillips+D@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I&#39;m guessing that containers will help with this, but I&#39;m not sure how.<br>
<br>
Say I have an int[][] of unknown length and I want to get the setIntersection of all int[]s. The only way I can see to do that is to intersect the first two elements and iterate over them storing into an int[] which can be used in an intersection with the next element...<br>

<br>
I realize that a Range is meant to be view of a container, but it seems to me that containing a Range can be just as useful. How might containers improve this situation?<br>
<br></blockquote><div>I don&#39;t know if containers can help, but ranges of ranges do exist, with no problem.<br><br>auto lists = [[0,1,2,3], [4,5,6], [7], [], [8]];<br><br>auto mapped = map!((int[] arr) { return map!&quot;a*a&quot;(arr))(lists); // The delegate literal takes an array and returns an array.<br>
<br>Here, the topology is preserved and you get back a range of ranges, with the same lengths and rank <br><br>[[0,1,4,9], [16,25,36], [49], [], [64]]<br><br> </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

<br>
.\setint.d(13): Error: cannot implicitly convert expression (setIntersection(res<br>
ult,range)) of type SetIntersection!(less,SetIntersection!(less,int[],int[]),int<br>
[]) to SetIntersection!(less,int[],int[])<br>
</blockquote></div><br><br>SetIntersection is lazy: it works for ranges of unknown length, even infinite ones, and calculates only the intersection elements that you ask for. This means in D storing it in a struct, which has a type encoding the entire operation.<br>
So the type of result is indeed SetIntersection!(less, int[],int[]), whereas a new application will wrap another layer around it. You have a matriochka of types, which cannot be converted.<br><br>But you can &#39;collapse&#39; the result using array() to get back an array, if you&#39;re certain your result is finite in length. Let&#39;s call that fuse:<br>
<br>T[] fuse(T)(T[] a1, T[] a2) {<br>    return array(setIntersection(a1,a2));<br>}<br><br>What you&#39;re doing in your case is accumulating a result, so it&#39;s a fold/reduce operation:<br><br>auto intersect = reduce ! fuse (lists);<br>
<br>Which works...<br><br>As setIntersection takes a variable number of ranges, it&#39;d be interesting to have a way to &#39;crack open&#39; a range of ranges and transform it into a tuple of ranges. The problem is, a tuple has a compile-time length. If lists was an int[][3], you could make a template transforming it into a TypeTuple!(int[],int[],int[]) that you can pass to setIntersection, opening it with .expand.<br>
<br>But that&#39;s not possible in general for a dynamic array of dynamic arrays, as its number of elements is only known at runtime. Maybe that&#39;s what you where asking?<br><br>I did a recursive map a few weeks ago, wich maps a function on the innermost elements of a range of ranges of ... of ranges.<br>
I was looking for operations that preserve the topology (mapping on a tree and returning a tree of the same shape).<br><br><br>  Philippe<br><br><br><br>