| 1 | // Copyright (c) 2007 Omer Rauchwerger (a.k.a rauchy) (omer@rauchy.net) |
|---|
| 2 | // All rights reserved. |
|---|
| 3 | // |
|---|
| 4 | // This file is part of Regionerate. |
|---|
| 5 | // |
|---|
| 6 | // This program is free software; you can redistribute it and/or modify it |
|---|
| 7 | // under the terms of the GNU General Public License as published by |
|---|
| 8 | // the Free Software Foundation; either version 3 of the License, |
|---|
| 9 | // or (at your option) any later version. |
|---|
| 10 | // |
|---|
| 11 | // This program is distributed in the hope that it will be useful, |
|---|
| 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 14 | // GNU General Public License for more details. |
|---|
| 15 | |
|---|
| 16 | // You should have received a copy of the GNU General Public License |
|---|
| 17 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 18 | |
|---|
| 19 | using System.Collections.Generic; |
|---|
| 20 | using System.Reflection; |
|---|
| 21 | |
|---|
| 22 | namespace Rauchy.Regionerate.Domain.Components.Extensions |
|---|
| 23 | { |
|---|
| 24 | public static class IListExtensions |
|---|
| 25 | { |
|---|
| 26 | #region�Methods�(2)� |
|---|
| 27 | |
|---|
| 28 | //�Public�Methods�(2)� |
|---|
| 29 | |
|---|
| 30 | /// <summary> |
|---|
| 31 | /// Slices an <see cref="IList"/> into a map by unique values of a single property. |
|---|
| 32 | /// </summary> |
|---|
| 33 | /// <example> |
|---|
| 34 | /// Suppose you have a type called Foo with a string property called Bar and you have 3 instances of Foo inside |
|---|
| 35 | /// a list. 2 of these instances have the value "hello" as Bar and 1 instance has the value "goodbye". |
|---|
| 36 | /// Running Slice on the list will return an <see cref="IDictionary"/> which contains two items - |
|---|
| 37 | /// the first item will be keyd 'hello' and its value will be a list containing the 2 instances |
|---|
| 38 | /// that contains "hello" and the second item will be keyd 'goodbye' and its value will be |
|---|
| 39 | /// a list that contains the single instance which contains "goodbye". |
|---|
| 40 | /// </example> |
|---|
| 41 | /// <remarks> |
|---|
| 42 | /// The original list does not need to be sorted. |
|---|
| 43 | /// </remarks> |
|---|
| 44 | /// <typeparam name="T">The type inside the list.</typeparam> |
|---|
| 45 | /// <param name="list">The <see cref="IList"/> to operate on.</param> |
|---|
| 46 | /// <param name="propertyInfo">The <see cref="PropertyInfo"/> to slice by.</param> |
|---|
| 47 | /// <returns>A map of lists, each containing distinct values in the provided property info.</returns> |
|---|
| 48 | public static IDictionary<object, IList<T>> Slice<T>( this IList<T> list, PropertyInfo propertyInfo ) |
|---|
| 49 | { |
|---|
| 50 | IDictionary<object, IList<T>> slices = new Dictionary<object, IList<T>>(); |
|---|
| 51 | foreach ( T t in list ) |
|---|
| 52 | { |
|---|
| 53 | // Get the value of propertyInfo. |
|---|
| 54 | object value = propertyInfo.GetValue( t, null ); |
|---|
| 55 | |
|---|
| 56 | // Add it to slices. |
|---|
| 57 | if ( slices.Keys.Contains( value ) ) |
|---|
| 58 | { |
|---|
| 59 | // slices already has a slice for this value. |
|---|
| 60 | slices[ value ].Add( t ); |
|---|
| 61 | } |
|---|
| 62 | else |
|---|
| 63 | { |
|---|
| 64 | // there is no slice for this value inside slices, create a new slice. |
|---|
| 65 | IList<T> newSlice = new List<T>(); |
|---|
| 66 | newSlice.Add( t ); |
|---|
| 67 | slices.Add( value, newSlice ); |
|---|
| 68 | } |
|---|
| 69 | } |
|---|
| 70 | |
|---|
| 71 | return slices; |
|---|
| 72 | } |
|---|
| 73 | |
|---|
| 74 | /// <summary> |
|---|
| 75 | /// Slices an <see cref="IList"/> into a map by unique values of a single property. |
|---|
| 76 | /// </summary> |
|---|
| 77 | /// <example> |
|---|
| 78 | /// Suppose you have a type called Foo with a string property called Bar and you have 3 instances of Foo inside |
|---|
| 79 | /// a list. 2 of these instances have the value "hello" as Bar and 1 instance has the value "goodbye". |
|---|
| 80 | /// Running Slice on the list will return an <see cref="IDictionary"/> which contains two items - |
|---|
| 81 | /// the first item will be keyd 'hello' and its value will be a list containing the 2 instances |
|---|
| 82 | /// that contains "hello" and the second item will be keyd 'goodbye' and its value will be |
|---|
| 83 | /// a list that contains the single instance which contains "goodbye". |
|---|
| 84 | /// </example> |
|---|
| 85 | /// <remarks> |
|---|
| 86 | /// The original list does not need to be sorted. |
|---|
| 87 | /// </remarks> |
|---|
| 88 | /// <typeparam name="T">The type inside the list.</typeparam> |
|---|
| 89 | /// <param name="list">The <see cref="IList"/> to operate on.</param> |
|---|
| 90 | /// <param name="propertyName">The name of the property to slice by.</param> |
|---|
| 91 | /// <returns>A map of lists, each containing distinct values in the provided property info.</returns> |
|---|
| 92 | public static IDictionary<object, IList<T>> Slice<T>( this IList<T> list, string propertyName ) |
|---|
| 93 | { |
|---|
| 94 | PropertyInfo propertyInfo = typeof ( T ).GetProperty( propertyName ); |
|---|
| 95 | return Slice( list, propertyInfo ); |
|---|
| 96 | } |
|---|
| 97 | |
|---|
| 98 | #endregion�Methods� |
|---|
| 99 | } |
|---|
| 100 | } |
|---|