Skip to content

Instantly share code, notes, and snippets.

@wipiano
Last active March 8, 2018 13:10
Show Gist options
  • Save wipiano/faa21d8b514163fa9a17ace8b92a21d8 to your computer and use it in GitHub Desktop.
Save wipiano/faa21d8b514163fa9a17ace8b92a21d8 to your computer and use it in GitHub Desktop.
LINQ で指定したキーだけ使って Distinct, Except とかする ref: https://qiita.com/wipiano/items/4437e80dc99a30f303f0
public class MyClass
{
public int Id { get; set; }
public double Value { get; set; }
}
public static IEnumerable<TItem> Distinct<TItem, TKey>(this IEnumerable<TItem> source, Func<TItem, TKey> keySelector)
{
IEnumerable<TItem> Enumerate()
{
var set = new HashSet<TKey>();
foreach (var item in source)
if (set.Add(keySelector(item))) yield return item;
}
if (source == null)
throw new ArgumentNullException(nameof(source));
if (keySelector == null)
throw new ArgumentNullException(nameof(keySelector));
return Enumerate();
}
var data = new []
{
new MyClass { Id = 1, Value = 1.0 },
new MyClass { Id = 2, Value = 2.0 },
new MyClass { Id = 1, Value = 0.5 },
};
// {Id = 1, Value = 1.0}, {Id = 2, Value = 2.0}
var result = data.Distinct(x => x.Id);
public static IEnumerable<TItem> Except<TItem, TKey>(this IEnumerable<TItem> first, IEnumerable<TItem> second, Func<TItem, TKey> keySelector)
{
IEnumerable<TItem> Enumerate()
{
var set = new HashSet<TKey>(second.Select(keySelector));
foreach (var item in first)
if (set.Add(keySelector(item))) yield return item;
}
if (first == null)
throw new ArgumentNullException(nameof(first));
if (second == null)
throw new ArgumentNullException(nameof(second));
if (keySelector == null)
throw new ArgumentNullException(nameof(keySelector));
return Enumerate();
}
var first = new []
{
new MyClass { Id = 1, Value = 1.0 },
new MyClass { Id = 2, Value = 2.0 },
new MyClass { Id = 3, Value = 3.0 },
};
var second = new []
{
new MyClass { Id = 1, Value = 100.0 }
};
// {Id = 2, Value = 2.0}, {Id = 3, Value = 3.0}
var result = first.Except(second, x => x.Id);
public static IEnumerable<TItem> Union<TItem, TKey>(this IEnumerable<TItem> first, IEnumerable<TItem> second, Func<TItem, TKey> keySelector)
{
IEnumerable<TItem> Enumerate()
{
var set = new HashSet<TKey>();
foreach (var item in first)
if (set.Add(keySelector(item))) yield return item;
foreach (var item in second)
if (set.Add(keySelector(item))) yield return item;
}
if (first == null)
throw new ArgumentNullException(nameof(first));
if (second == null)
throw new ArgumentNullException(nameof(second));
if (keySelector == null)
throw new ArgumentNullException(nameof(keySelector));
return Enumerate();
}
var first = new []
{
new MyClass { Id = 1, Value = 1.0 },
new MyClass { Id = 2, Value = 2.0 },
new MyClass { Id = 3, Value = 3.0 },
};
var second = new []
{
new MyClass { Id = 1, Value = 100.0 },
new MyClass { Id = 4, Value = 400.0 },
};
// {Id = 1, Value = 1.0}, {Id = 2, Value = 2.0}, {Id = 3, Value = 3.0}, {Id = 4, Value = 400.0}
var result = first.Union(second, x => x.Id);
public static IEnumerable<TItem> Intersect<TItem, TKey>(this IEnumerable<TItem> first, IEnumerable<TItem> second, Func<TItem, TKey> keySelector)
{
IEnumerable<TItem> Enumerate()
{
var set = new HashSet<TKey>(second.Select(keySelector));
foreach (var item in first)
if (!set.Add(keySelector(item))) yield return item;
}
if (first == null)
throw new ArgumentNullException(nameof(first));
if (second == null)
throw new ArgumentNullException(nameof(second));
if (keySelector == null)
throw new ArgumentNullException(nameof(keySelector));
return Enumerate();
}
var first = new []
{
new MyClass { Id = 1, Value = 1.0 },
new MyClass { Id = 2, Value = 2.0 },
new MyClass { Id = 3, Value = 3.0 },
};
var second = new []
{
new MyClass { Id = 1, Value = 100.0 },
new MyClass { Id = 4, Value = 400.0 },
};
// {Id = 1, Value = 1.0}
var result = first.Intersect(second, x => x.Id);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment