-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAggregateExtensions.cs
More file actions
106 lines (88 loc) · 2.93 KB
/
AggregateExtensions.cs
File metadata and controls
106 lines (88 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace TouchDirWithFileDate
{
static class AggregateExtensions
{
public static TSource Median<TSource>(this IEnumerable<TSource> source)
where TSource : struct, INumber<TSource>
=> Median<TSource, TSource>(source);
public static TResult Median<TSource, TResult>(this IEnumerable<TSource> source)
where TSource : struct, INumber<TSource>
where TResult : struct, INumber<TResult>
{
var array = source.ToArray();
var length = array.Length;
if (length == 0)
{
throw new InvalidOperationException("Sequence contains no elements.");
}
Array.Sort(array);
var index = length / 2;
var value = TResult.CreateChecked(array[index]);
if (length % 2 == 1)
{
return value;
}
var sum = value + TResult.CreateChecked(array[index - 1]);
return sum / TResult.CreateChecked(2);
}
}
public class MedianTests
{
[Test]
public void Median_PopulatedCollection_ReturnsCorrectResult()
{
// Arrange
var source = new List<decimal> { 4.5m, 2.0m, 1.2m, 3.9m, 6.7m };
var expected = 3.9m;
// Act
var actual = source.Median<decimal, decimal>();
// Assert
Assert.AreEqual(expected, actual);
}
[Test]
public void Median_AverageIsUsedIfUnableToGetMedian()
{
// Arrange
var source = new List<decimal> { 1m, 2m };
var expected = source.Average(); //if median doesn't exist, use average
// Act
var actual = source.Median<decimal, decimal>();
// Assert
Assert.AreEqual(expected, actual);
}
[Test]
public void Median_EmptyCollection_ThrowsInvalidOperationException()
{
// Arrange
var source = new List<decimal>();
// Act
// Assert
Assert.Throws<InvalidOperationException>(() => source.Median<decimal, decimal>());
}
[Test]
public void Median_NullCollection_ThrowsArgumentNullException()
{
// Arrange
List<decimal> source = null!;
// Act
// Assert
Assert.Throws<System.ArgumentNullException>(() => source.Median<decimal, decimal>());
}
[Test]
public void Median_CollectionWithOneValue_ReturnsCorrectResult()
{
// Arrange
var source = new List<decimal> { 4.5m };
var expected = 4.5m;
// Act
var actual = source.Median<decimal, decimal>();
// Assert
Assert.AreEqual(expected, actual);
}
}
}