I was recently writing a test for an engine that takes in 2 points and calculates the mileage between them. I had already been given 2 distinct list of points (zips in this case) as input, but for the purposes of this demo I will just stub them out. It is irrelevant really what the engine takes in, I just wanted to show case this “new to me” method on Enumerable called Zip.
[Test] public void NonParallelMileageTest() { var originPoints= PointHelper.GetPoints(PointType.Origin); var destinationPoints = PointHelper.GetPoints(PointType.Destination); IEnumerable<Point> origin100Points = originPoints.Take(100); IEnumerable<Point> destination100Points = destinationPoints.Take(100).Reverse(); //to ensure most of the points are different List<Tuple<string, string>> originDestinationPair =origin100Points.Zip(destination100Points, (origin, destination) => new Tuple<string, string>(origin.Zip, destination.Zip)).ToList(); //contains 100 elements foreach (Tuple<string, string> pair in originDestinationPair { MileageHelper.GetMileage(pair.Item1, pair.Item2); Assert.Greater(mileage, 0); } }
One enumerable can “zip” another enumerable, and input is
1. the other enumerable, and
2. a lambda expression with inputs of an item from each enumerable and how you want to create your new object.
In this case I am creating a Tuple (it’s ok, I’m in a test).
Pretty cool.
One other thing to be aware of about the method: if the 2 enumerables you are “zipping up” don’t contain the same amount of elements, it will use the lowest collection count. See comment above in the sample that the resulting list will contain 100 elements.
So this example only contains 99 elements,
[Test] public void ParallelMileageTest() { var originPoints= PointHelper.GetPoints(PointType.Origin); var destinationPoints = PointHelper.GetPoints(PointType.Destination); IEnumerable<Point> origin100Points = originPoints.Take(100); IEnumerable<Point> destination100Points = destinationPoints.Take(99).Reverse(); //to ensure most of the points are different List<Tuple<string, string>> originDestinationPair = origin100Points.Zip(destination100Points, (origin, destination) => new Tuple<string, string>(origin.Zip, destination.Zip)).ToList(); //contains 99 elements Parallel.ForEach(originDestinationPair , (pair) => MileageHelper.GetMileage(pair.Item1, pair.Item2) }
I have really been meaning to blog about the Parallel namespace as I have been using it quite a bit lately and love it. More on that later.
Leave a Comment