Last active
August 29, 2015 14:14
-
-
Save kamiyaowl/ff9a05537f29dca09417 to your computer and use it in GitHub Desktop.
LinqExtension
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Linq.Expressions; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace ConsoleApplication3 { | |
class Program { | |
static void Main(string[] args) { | |
var src = new[] { 10, 20, 30, 40, 50 }; | |
src.DebugPrint("src"); | |
src.ForEach(x => Console.WriteLine(x)); | |
src.ForEach((x, i) => Console.WriteLine("src[{0}] : {1}", i, x)); | |
src.DebugPrint("src").Select(x => x / 2).DebugPrint("after (x => x / 2)"); | |
src.Append(60).DebugPrint("Append 60"); | |
0.Append(src).DebugPrint("Append src"); | |
src.Insert(2, 25).DebugPrint("Insert (2,25)"); | |
src.Insert(3, new[] { 32, 34, 36, 38 }).DebugPrint("Insert (3,[32, 34, 36, 38])"); | |
src.Pipe(x => Console.WriteLine("src.Debug({0})", x)) | |
.Select(x => x * 2) | |
.Pipe(x => Console.WriteLine("src.Select(x => x * 2).Debug({0})", x)) | |
.Where(x => x > 50) | |
.DebugPrint("src |> select x * 2 |> where x > 50"); | |
Enumerable.Range('a', 26).Select(x => (char)x).ToText().WriteLine("ToText() : {0}"); | |
LinqExtension.RandomSource().Take(10).DebugPrint("RandomSource"); | |
var monteMax = 1000; | |
var randomSource = LinqExtension.RandomSourceDouble(); | |
var monteCount = randomSource.Zip(randomSource, (x, y) => x * x + y * y < 1.0).Take(monteMax).Count(x => x); | |
(monteCount / (double)monteMax * 4.0).WriteLine("PI = {0}"); | |
src.Shuffle().DebugPrint("src Shuffle"); | |
//OrderBy -> SequenceEqualでもいける | |
var src1 = new[] { 1, 2, 3 }; | |
var src2 = new[] { 1, 3, 2 }; | |
var src3 = new[] { 1, 3 }; | |
src1.DebugPrint("src1"); | |
src2.DebugPrint("src2"); | |
src3.DebugPrint("src3"); | |
(src1 == src2).WriteLine("src1 == src2 => {0}"); | |
(src1 == src3).WriteLine("src1 == src3 => {0}"); | |
(src2 == src3).WriteLine("src2 == src3 => {0}"); | |
src1.SeqMatch(src2).WriteLine("src1 SeqMatch src2 => {0}"); | |
src1.SeqMatch(src3).WriteLine("src1 SeqMatch src3 => {0}"); | |
src2.SeqMatch(src3).WriteLine("src2 SeqMatch src3 => {0}"); | |
var src4 = new[] { 1, 2, 3, 4, 5 }; | |
var src5 = new[] { "A", "B", "C", "D", "E" }; | |
src4.DebugPrint("src4"); | |
src5.DebugPrint("src5"); | |
src4.Zip(src5, (i, str) => str + i.ToString()).DebugPrint("ZipSelect"); | |
var src6 = new[] { 1, 3, 4, 5, 8, 9, 10, 11, 13, 3, 0, -5, -7, -20 }; | |
src6.DebugPrint("src6"); | |
src6.DiffSelect((x, y) => y - x).DebugPrint("DiffSelect (x,y) => y - x"); | |
var src7 = new[] { 1, 9, 10, 12, 15, 18 }; | |
var src8 = new[] { 2, 5, 6, 11, 13, 14, 15, 20, 30 }; | |
src7.DebugPrint("src7"); | |
src8.DebugPrint("src8"); | |
src7.Merge(src8).DebugPrint("src7 merge src8"); | |
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
string str1 = "hello"; | |
string str2 = null; | |
str1.WriteLine("str1 = {0}"); | |
str2.WriteLine("str2 = {0}"); | |
str1.NullPropagation(str => str.ToUpper()).WriteLine("str1 IsNull(ToUpper) => {0}"); | |
str2.NullPropagation(str => str.ToUpper()).WriteLine("str2 IsNull(ToUpper) => {0}"); | |
//C# 6.0のNull条件演算子で代用可能 | |
//str1?.ToUpper().WriteLine(); | |
Console.Read(); | |
} | |
} | |
static class Extension { | |
public static U NullPropagation<T, U>(this T src, Func<T, U> f, U initial = default(U)) { | |
return (src != null) ? f(src) : initial; | |
} | |
public static void WriteLine(this object obj, string text = "{0}") { | |
Console.WriteLine(text, obj); | |
} | |
} | |
static class LinqExtension { | |
public static IEnumerable<T> Merge<T>(this IEnumerable<T> src1, IEnumerable<T> src2) { | |
return src1.Concat(src2).OrderBy(x => x); | |
} | |
public static IEnumerable<U> DiffSelect<T, U>(this IEnumerable<T> src, Func<T, T, U> selector) { | |
return src.Zip(src.Skip(1), selector); | |
} | |
public static bool SeqMatchArray<T>(this T[] a1, T[] a2) { | |
if (a1.Length != a2.Length) return false; | |
return SeqMatch(a1, a2); | |
} | |
public static bool SeqMatch<T>(this IEnumerable<T> a1, IEnumerable<T> a2) { | |
return a1.All(x => a2.Contains(x)); | |
} | |
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> src) { | |
return src.Zip(RandomSource(), (x, i) => new { Index = i, Value = x }).OrderBy(x => x.Index).Select(x => x.Value); | |
} | |
private static Random random = new Random(); | |
public static IEnumerable<double> RandomSourceDouble(double min = 0, double max = 1.0) { | |
var d = max - min; | |
while (true) { | |
yield return random.NextDouble() * d - min; | |
} | |
} | |
public static IEnumerable<int> RandomSource(int min = 0, int max = int.MaxValue) { | |
var d = max - min; | |
while (true) { | |
yield return random.Next(d) - min; | |
} | |
} | |
public static string ToText(this IEnumerable<char> src) { | |
return new string(src.ToArray()); | |
} | |
public static IEnumerable<T> Pipe<T>(this IEnumerable<T> src, Action<T, int> func) { | |
foreach (var item in src.Select((x, i) => new { Index = i, Value = x })) { | |
func(item.Value, item.Index); | |
yield return item.Value; | |
} | |
} | |
public static IEnumerable<T> Pipe<T>(this IEnumerable<T> src, Action<T> func) { | |
foreach (var item in src) { | |
func(item); | |
yield return item; | |
} | |
} | |
public static IEnumerable<T> Insert<T>(this IEnumerable<T> src, int index, T insertItem) { | |
foreach (var item in src.Select((x, i) => new { X = x, I = i })) { | |
if (item.I == index) yield return insertItem; | |
yield return item.X; | |
} | |
} | |
public static IEnumerable<T> Insert<T>(this IEnumerable<T> src, int index, IEnumerable<T> insertSrc) { | |
foreach (var item in src.Select((x, i) => new { X = x, I = i })) { | |
if (item.I == index) | |
foreach (var insertItem in insertSrc) | |
yield return insertItem; | |
yield return item.X; | |
} | |
} | |
public static IEnumerable<T> Append<T>(this IEnumerable<T> head, T tail) { | |
foreach (var item in head) | |
yield return item; | |
yield return tail; | |
} | |
public static IEnumerable<T> Append<T>(this T head, IEnumerable<T> tail) { | |
yield return head; | |
foreach (var item in tail) | |
yield return item; | |
} | |
public static IEnumerable<T> DebugPrint<T>(this IEnumerable<T> src, string header = "") { | |
Console.Write("{0}[", header.Length == 0 ? "" : header + " : "); | |
foreach (var item in src) { | |
Console.Write("{0},", item); | |
} | |
Console.WriteLine("]"); | |
return src; | |
} | |
public static void ForEach<T>(this IEnumerable<T> src, Action<T, int> func) { | |
foreach (var item in src.Select((x, i) => new { Value = x, Index = i })) | |
func(item.Value, item.Index); | |
} | |
public static void ForEach<T>(this IEnumerable<T> src, Action<T> func) { | |
foreach (var item in src) | |
func(item); | |
} | |
public static IEnumerable<T> CrossMerge<T>(this IEnumerable<T> first, IEnumerable<T> second) { | |
if (first.Count() == 0) yield break; | |
int j = 0; | |
foreach (var item in first.Zip(second, (f, s) => new { First = f, Second = s })) { | |
yield return item.First; | |
yield return item.Second; | |
++j; | |
} | |
if (j < first.Count()) { | |
yield return first.Last(); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
src : [10,20,30,40,50,] | |
10 | |
20 | |
30 | |
40 | |
50 | |
src[0] : 10 | |
src[1] : 20 | |
src[2] : 30 | |
src[3] : 40 | |
src[4] : 50 | |
src : [10,20,30,40,50,] | |
after (x => x / 2) : [5,10,15,20,25,] | |
Append 60 : [10,20,30,40,50,60,] | |
Append src : [0,10,20,30,40,50,] | |
Insert (2,25) : [10,20,25,30,40,50,] | |
Insert (3,[32, 34, 36, 38]) : [10,20,30,32,34,36,38,40,50,] | |
src |> select x * 2 |> where x > 50 : [src.Debug(10) | |
src.Select(x => x * 2).Debug(20) | |
src.Debug(20) | |
src.Select(x => x * 2).Debug(40) | |
src.Debug(30) | |
src.Select(x => x * 2).Debug(60) | |
60,src.Debug(40) | |
src.Select(x => x * 2).Debug(80) | |
80,src.Debug(50) | |
src.Select(x => x * 2).Debug(100) | |
100,] | |
ToText() : abcdefghijklmnopqrstuvwxyz | |
RandomSource : [1200895799,584985855,1787317049,820738086,1755496255,914737898,1427789998,225642398,2102230679,1134888207,] | |
PI = 3.216 | |
src Shuffle : [40,30,50,10,20,] | |
src1 : [1,2,3,] | |
src2 : [1,3,2,] | |
src3 : [1,3,] | |
src1 == src2 => False | |
src1 == src3 => False | |
src2 == src3 => False | |
src1 SeqMatch src2 => True | |
src1 SeqMatch src3 => False | |
src2 SeqMatch src3 => False | |
src4 : [1,2,3,4,5,] | |
src5 : [A,B,C,D,E,] | |
ZipSelect : [A1,B2,C3,D4,E5,] | |
src6 : [1,3,4,5,8,9,10,11,13,3,0,-5,-7,-20,] | |
DiffSelect (x,y) => y - x : [2,1,1,3,1,1,1,2,-10,-3,-5,-2,-13,] | |
src7 : [1,9,10,12,15,18,] | |
src8 : [2,5,6,11,13,14,15,20,30,] | |
src7 merge src8 : [1,2,5,6,9,10,11,12,13,14,15,15,18,20,30,] | |
str1 = hello | |
str2 = | |
str1 IsNull(ToUpper) => HELLO | |
str2 IsNull(ToUpper) => |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment