1: using System;
2: using System.Collections.Generic;
3: using System.IO;
4: using System.Linq;
5: using System.Web;
6: using System.Xml.Serialization;
7:
8: ////////////////////////////////////////////////////////////////////////////
9:
10: /// <summary publish="true">
11: /// Extention methods for different class objects.
12: /// </summary>
13: ///
14: /// <remarks>
15: /// Copyright © 2001-2021 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
16: ///
17: /// This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
18: /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
19: ///
20: /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
21: /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
22: ///
23: /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
24: ///
25: /// Copyright notice: This notice may not be removed or altered from any source distribution.
26: /// </remarks>
27:
28: public static class Extention
29: {
30: private static Dictionary<int, int> listHashCodeToIndexDictionary = new Dictionary<int, int>();
31:
32: ////////////////////////////////////////////////////////////////////////////
33:
34: /// <summary>
35: ///
36: /// </summary>
37: public static T XmlDeserializeFromString<T>(this string objectData)
38: {
39: return (T)XmlDeserializeFromString(objectData, typeof(T));
40: }
41:
42: ////////////////////////////////////////////////////////////////////////////
43:
44: /// <summary>
45: ///
46: /// </summary>
47: public static object XmlDeserializeFromString(this string objectData, Type type)
48: {
49: var serializer = new XmlSerializer(type);
50: object result;
51:
52: using (TextReader reader = new StringReader(objectData))
53: {
54: result = serializer.Deserialize(reader);
55: }
56:
57: return result;
58: }
59:
60: ////////////////////////////////////////////////////////////////////////////
61:
62: /// <summary>
63: /// Extends strings to return bool values
64: /// <see href="http://stackoverflow.com/questions/16205436/convert-toboolean-fails-with-0-value"/>
65: /// </summary>
66: public static bool ToBool(this string str)
67: {
68: bool b;
69: string cleanValue;
70:
71: cleanValue = (str ?? "").Trim();
72:
73: if (string.Equals(cleanValue, "False", StringComparison.OrdinalIgnoreCase)) b = false;
74: else b = (string.Equals(cleanValue, "True", StringComparison.OrdinalIgnoreCase)) || (cleanValue != "0");
75:
76: return b;
77: }
78:
79: /*
80: ////////////////////////////////////////////////////////////////////////////
81:
82: /// <summary>
83: ///
84: /// </summary>
85: public static bool IsInMenuPath(this SiteMapNode thisnode, SiteMapNode node)
86: {
87: var temp = node;
88:
89: while (temp != null && temp != thisnode) temp = temp.ParentNode;
90:
91: return temp != null;
92: }
93: */
94:
95: ////////////////////////////////////////////////////////////////////////////
96: ////////////////////////////////////////////////////////////////////////////
97:
98: /// <summary>
99: /// Pick a random value from List
100: ///<see href="http://stackoverflow.com/questions/2019417/access-random-item-in-list"/>
101: /// </summary>
102: public static T PickRandom<T>(this IEnumerable<T> source)
103: {
104: return source.PickRandom(1).Single();
105: }
106:
107: ////////////////////////////////////////////////////////////////////////////
108:
109: /// <summary>
110: ///
111: /// </summary>
112: public static IEnumerable<T> PickRandom<T>(this IEnumerable<T> source, int count)
113: {
114: return source.Shuffle().Take(count);
115: }
116:
117: ////////////////////////////////////////////////////////////////////////////
118:
119: /// <summary>
120: ///
121: /// </summary>
122: public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
123: {
124: return source.OrderBy(x => Guid.NewGuid());
125: }
126:
127: ////////////////////////////////////////////////////////////////////////////
128: ////////////////////////////////////////////////////////////////////////////
129:
130: /// <summary>
131: ///
132: /// </summary>
133: public static bool JustStartedOrRolledOver<T>(this IList<T> list)
134: {
135: return JustStarted(list) || RolledOver(list);
136: }
137:
138: ////////////////////////////////////////////////////////////////////////////
139:
140: /// <summary>
141: ///
142: /// </summary>
143: private static bool JustStarted<T>(this IList<T> list)
144: {
145: var listHashCode = list.GetHashCode();
146:
147: if (!listHashCodeToIndexDictionary.ContainsKey(listHashCode))
148: {
149: listHashCodeToIndexDictionary[listHashCode] = 0;
150: }
151:
152: return listHashCodeToIndexDictionary[listHashCode] == 0;
153: }
154:
155: ////////////////////////////////////////////////////////////////////////////
156:
157: /// <summary>
158: ///
159: /// </summary>
160: private static bool RolledOver<T>(this IList<T> list)
161: {
162: var listHashCode = list.GetHashCode();
163:
164: if (!listHashCodeToIndexDictionary.ContainsKey(listHashCode))
165: {
166: listHashCodeToIndexDictionary[listHashCode] = 0;
167: }
168:
169: return listHashCodeToIndexDictionary[listHashCode] % list.Count == 0;
170: }
171:
172: ////////////////////////////////////////////////////////////////////////////
173:
174: /// <summary>
175: ///
176: /// </summary>
177: public static T Next<T>(this IList<T> list)
178: {
179: var listHashCode = list.GetHashCode();
180:
181: if (!listHashCodeToIndexDictionary.ContainsKey(listHashCode))
182: {
183: listHashCodeToIndexDictionary[listHashCode] = 0;
184: }
185:
186: return list[listHashCodeToIndexDictionary[listHashCode]++ % list.Count];
187: }
188:
189: ////////////////////////////////////////////////////////////////////////////
190:
191: /// <summary>
192: ///
193: /// </summary>
194: public static T RandomThenNext<T>(this IList<T> list)
195: {
196: var listHashCode = list.GetHashCode();
197:
198: if (!listHashCodeToIndexDictionary.ContainsKey(listHashCode))
199: {
200: listHashCodeToIndexDictionary[listHashCode] = Ia.Cl.Model.Default.Random(list.Count);
201: }
202:
203: return list[listHashCodeToIndexDictionary[listHashCode]++ % list.Count];
204: }
205:
206: ////////////////////////////////////////////////////////////////////////////
207:
208: /// <summary>
209: ///
210: /// </summary>
211: public static T Next<T>(this IList<T> list, out int index, out int count)
212: {
213: var listHashCode = list.GetHashCode();
214:
215: if (!listHashCodeToIndexDictionary.ContainsKey(listHashCode))
216: {
217: listHashCodeToIndexDictionary[listHashCode] = 0;
218: }
219:
220: count = list.Count;
221: index = listHashCodeToIndexDictionary[listHashCode] % list.Count;
222:
223: var t = Next(list);
224:
225: return t;
226: }
227:
228: ////////////////////////////////////////////////////////////////////////////
229:
230: /// <summary>
231: ///
232: /// </summary>
233: public static T Next<T>(this IList<T> list, int index)
234: {
235: var i = index;
236:
237: return Next(list, ref i);
238: }
239:
240: ////////////////////////////////////////////////////////////////////////////
241:
242: /// <summary>
243: ///
244: /// </summary>
245: public static T Next<T>(this IList<T> list, ref int index, out int index2, out int count)
246: {
247: var listHashCode = list.GetHashCode();
248:
249: if (!listHashCodeToIndexDictionary.ContainsKey(listHashCode))
250: {
251: listHashCodeToIndexDictionary[listHashCode] = 0;
252: }
253:
254: count = list.Count;
255: index2 = index;
256:
257: var t = Next(list, ref index);
258:
259: return t;
260: }
261:
262: ////////////////////////////////////////////////////////////////////////////
263:
264: /// <summary>
265: ///
266: /// </summary>
267: public static T Next<T>(this IList<T> list, ref int index)
268: {
269: var listHashCode = list.GetHashCode();
270:
271: if (!listHashCodeToIndexDictionary.ContainsKey(listHashCode))
272: {
273: listHashCodeToIndexDictionary[listHashCode] = 0;
274: }
275:
276: if (index < 0 || index >= list.Count) throw new ArgumentOutOfRangeException("Index value: " + index + " is not within list range: 0," + (list.Count - 1));
277:
278: listHashCodeToIndexDictionary[listHashCode] = index;
279:
280: index = ++index % list.Count;
281:
282: return list[listHashCodeToIndexDictionary[listHashCode]++ % list.Count];
283: }
284:
285: ////////////////////////////////////////////////////////////////////////////
286:
287: /// <summary>
288: ///
289: /// </summary>
290: public static T NextOf<T>(this IList<T> list, T item)
291: {
292: return list[(list.IndexOf(item) + 1) == list.Count ? 0 : (list.IndexOf(item) + 1)];
293: }
294:
295: ////////////////////////////////////////////////////////////////////////////
296: ////////////////////////////////////////////////////////////////////////////
297:
298: /// <summary>
299: /// List get next element or get the first
300: ///<see href="https://stackoverflow.com/questions/22595655/how-to-do-a-dictionary-reverse-lookup"/>
301: /// </summary>
302: public static Dictionary<TValue, TKey> Reverse<TKey, TValue>(this IDictionary<TKey, TValue> source)
303: {
304: var dictionary = new Dictionary<TValue, TKey>();
305:
306: foreach (var entry in source)
307: {
308: if (entry.Value != null)
309: {
310: if (!dictionary.ContainsKey(entry.Value))
311: {
312: dictionary.Add(entry.Value, entry.Key);
313: }
314: }
315: }
316:
317: return dictionary;
318: }
319:
320: ////////////////////////////////////////////////////////////////////////////
321: ////////////////////////////////////////////////////////////////////////////
322:
323: public static IEnumerable<T> Flatten<T>(this T source, Func<T, IEnumerable<T>> selector)
324: {
325: // How to search Hierarchical Data with Linq
326: // https://stackoverflow.com/questions/18165460/how-to-search-hierarchical-data-with-linq
327:
328: return selector(source).SelectMany(c => Flatten(c, selector))
329: .Concat(new[] { source });
330: }
331:
332: ////////////////////////////////////////////////////////////////////////////
333: ////////////////////////////////////////////////////////////////////////////
334: }