iterating through a range, operating on last few elements at a time

H. S. Teoh via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Aug 13 20:12:00 PDT 2015


On Fri, Aug 14, 2015 at 02:42:26AM +0000, Laeeth Isharc via Digitalmars-d-learn wrote:
> I have a range that is an array of structs.  I would like to iterate
> through the range, calling a function with the prior k items in the
> range up to that point and storing the result of the function in a new
> range/array.
> 
> what's the best way to do this?  for low fixed k I could use zip with
> staggered slices (s[3..$],s[2..$-1],s[1..$-2],s[0..$-3]) and then map.
> I can't think of how to do it elegantly.
> 
> any thoughts?

Maybe something like this?

	import std.algorithm;
	import std.stdio;
	import std.range;
	
	auto slidingWindow(R)(R range, int k) {
		return iota(k).map!(i => range.save.drop(i))
			      .array
		              .transposed;
	}
	
	void main() {
		auto data = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
		writeln(data.slidingWindow(3));
	}

To apply the function to each slice, just write:

	data.slidingWindow(k).map!myFunc ...

I didn't figure out how to eliminate the short slices toward the end,
but all you need to do is to somehow drop the last (k-1) elements from
the range returned by slidingWindow.


T

-- 
Today's society is one of specialization: as you grow, you learn more and more about less and less. Eventually, you know everything about nothing.


More information about the Digitalmars-d-learn mailing list