NumberEnumerable.vala 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. namespace Invercargill {
  2. public abstract class NumberEnumerable<T, TSelf> : StickyPromotion<T, TSelf>, Promotion<T>, Equatable<Enumerable<T>> {
  3. protected abstract bool greater_than(T a, T b);
  4. protected abstract bool less_than(T a, T b);
  5. protected abstract bool equal_to(T a, T b);
  6. protected abstract T add(T a, T b);
  7. protected abstract T subtract(T a, T b);
  8. protected abstract T multiply(T a, T b);
  9. protected abstract T divide(T a, T b);
  10. protected abstract T zero();
  11. protected abstract T convert(int i);
  12. public virtual T average() {
  13. return divide(sum(), convert(count()));
  14. }
  15. public virtual T sum() {
  16. return aggrigate<T>(zero(), add);
  17. }
  18. public virtual T product() {
  19. T number = zero();
  20. var first = true;
  21. foreach (var item in this) {
  22. if(first) {
  23. first = false;
  24. number = item;
  25. continue;
  26. }
  27. number = multiply(number, item);
  28. }
  29. return number;
  30. }
  31. public new virtual T min() {
  32. T value = null;
  33. var first = true;
  34. foreach (var i in this) {
  35. if(first) {
  36. first = false;
  37. value = i;
  38. continue;
  39. }
  40. if(less_than(i, value)) {
  41. value = i;
  42. }
  43. }
  44. return value;
  45. }
  46. public new virtual T max() {
  47. T value = null;
  48. var first = true;
  49. foreach (var i in this) {
  50. if(first) {
  51. first = false;
  52. value = i;
  53. continue;
  54. }
  55. if(greater_than(i, value)) {
  56. value = i;
  57. }
  58. }
  59. return value;
  60. }
  61. public override Enumerable<T> wrap (Enumerable<T> enumerable) {
  62. inner = enumerable;
  63. return this;
  64. }
  65. public bool equals(Enumerable<T> other) {
  66. return this == other || this.matches(other, (a, b) => equal_to(a, b));
  67. }
  68. }
  69. }