The Fizz Buzz challenge is well-known and should not need any explanations, right?
I recently got a bit bored and came up with a solution for Fizz Buzz using LINQ and even asynchronous code and a lot of extension methods. Actually, it's only Extension methods!
So, I thought, let's share it and have a review of my code!
using System;
using System.Collections.Generic;
using System.Linq;
namespace FizzBuzzApp
{
using IntEnum = IEnumerable<int>;
using Pair = KeyValuePair<int, string>;
using PairEnum = IEnumerable<KeyValuePair<int, string>>;
using StringEnum = IEnumerable<string>;
public static class FizzBuzzClass
{
public static T DoThis<T>(this T data, Action<T> action) { action(data); return data; }
public static T DoThis<T>(this T data, Action action) { action(); return data; }
public static IEnumerable<T> DoThis<T>(this IEnumerable<T> data, Action<T> action) { foreach (var item in data) { action(item); yield return item; } }
public static T IfThis<T>(this T data, Func<T, bool> condition, Func<T, T> action) => condition(data) ? action(data) : data;
public static T IfThis<T>(this T data, Func<T, bool> condition, Func<T, T> onTrue, Func<T, T> onFalse) => condition(data) ? onTrue(data) : onFalse(data);
public static IntEnum MakeIntArray(this int count, int start = 0) => Enumerable.Range(start, count);
public static Pair NewPair(this int key) => new Pair(key, string.Empty);
public static Pair NewPair(this Pair pair, string data) => new Pair(pair.Key, data.Trim());
public static PairEnum MakePairs(this IntEnum data, bool asynchronous) => asynchronous ? data.AsParallel().Select(NewPair) : data.Select(NewPair);
public static IOrderedEnumerable<Pair> SortPairs(this IEnumerable<Pair> data) => data.OrderBy(p => p.Key);
public static bool IsFizz(this Pair data) => data.Key % 3 == 0;
public static Pair DoFizz(this Pair data) => data.NewPair("Fizz " + data.Value);
public static Pair Fizz(this Pair data) => data.IfThis(IsFizz, DoFizz);
public static PairEnum Fizz(this PairEnum data, bool asynchronous) => asynchronous ? data.AsParallel().Select(Fizz) : data.Select(Fizz);
public static bool IsBuzz(this Pair data) => data.Key % 5 == 0;
public static Pair DoBuzz(this Pair data) => data.NewPair(data.Value + " Buzz");
public static Pair Buzz(this Pair data) => data.IfThis(IsBuzz, DoBuzz);
public static PairEnum Buzz(this PairEnum data, bool asynchronous) => asynchronous ? data.AsParallel().Select(Buzz) : data.Select(Buzz);
public static bool IsNumber(this Pair data) => string.IsNullOrEmpty(data.Value);
public static Pair DoNumber(this Pair data) => data.NewPair(data.Key.ToString());
public static Pair Number(this Pair data) => data.IfThis(IsNumber, DoNumber);
public static PairEnum Number(this PairEnum data, bool asynchronous) => asynchronous ? data.AsParallel().Select(Number) : data.Select(Number);
public static StringEnum Values(this PairEnum data) => data.Select(p => p.Value);
public static string Combine(this StringEnum data) => string.Join(", ", data);
public static string FizzBuzz(this int count, bool asynchronous = false) =>
count.MakeIntArray()
.MakePairs(asynchronous)
.Fizz(asynchronous)
.Buzz(asynchronous)
.Number(asynchronous)
.SortPairs()
.Values()
.Combine();
}
To use it, just use 100.FizzBuzz(true);
for the asynchronous version.
Now, the thing is that it's full one-liner extension methods. It's definitely not something a beginner would write. But is it well-written for experts?