https://issues.dlang.org/show_bug.cgi?id=15651
--- Comment #4 from anonymous4 <dfj1es...@sneakemail.com> --- It will need separation between collections and iterators --- struct A { int[][] a; inout(int[])[] f() inout { return a.filter(x=>x!=null).array; } } inout(FilterCollection) filter(inout int[][] r, bool function(const int[]) pred) { return inout FilterCollection(r,pred); } struct FilterCollection { int[][] r; bool function(const int[]) pred; FilterRange range() const { auto r=FilterRange(&this); r.next(); return r; } } struct FilterRange { const(FilterCollection)* src; long index; inout(int[]) front(ref inout FilterCollection src2) { assert(src==&src2); return src2.r[index]; } void popFront() { index++; next(); } package void next() { foreach(i,a;src.r[index..$]) { if(src.pred(a)){ index+=i; return; } } index=src.r.length; } bool empty() { return index==src.r.length; } } inout(int[])[] array(inout FilterCollection src) { inout FilterCollection c=src; inout(int[])[] a; auto r=c.range; while(!r.empty) { //a~=r.front(c); inout int[] b=r.front(c); a~=b; r.popFront(); } return a; } int main() { A a; int[][4] b; b[0]=[1]; b[3]=[2]; a.a=b; int[][] c=a.f; assert(c.length==2); assert(c[0][0]==1); assert(c[1][0]==2); return 0; } --- --