www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - foreach filter by cast

reply "karl" <ultrano hotmail.com> writes:
Is there a brief way to iterate an array of objects, and process 
only objects of certain type (in either two ways, with/without 
inheritance)?

	foreach(p; obj.children){ // "KObj[] children"
		DPFile dfile = cast(DPFile)p;
		if(!dfile)continue;
		...
	}

I saw the std.algorithm.filter template helper could be used, but 
it's a bit complex:

foreach(unit; file.children.filter!(a => cast(KUnit)a)){
...
}


Thanks
Feb 14 2015
parent "karl" <ultrano hotmail.com> writes:
I found a solution I like a lot, with templated opApply:

class Cont{
	Thing[] kids;

	int opApply(T)(int delegate(ref T) dg){
		int result = 0;		
		for (int i = 0; i < kids.length; i++){
			T t = cast(T)kids[i];
			if(t){ result = dg(t);
				if (result) break;
			}
		}
		return result;
	}
}

class Thing{
	string name;
	this(){ name = "thing";}
}
class TBan : Thing{
	this(){ name = "tban";}
}
class TOne : Thing{
	this(){ name = "tone";}
}

void main(){
	Cont c = new Cont;
	c.kids ~= new TBan;
	c.kids ~= new TOne;
	c.kids ~= new TOne;
	c.kids ~= new Thing;

	foreach(TOne k; c){ // the "TOne k" declares the filtering-type
		writeln(k);
	}
}
Feb 14 2015