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: /// <summary>
82: ///
83: /// </summary>
84: public static bool IsInMenuPath(this SiteMapNode thisnode, SiteMapNode node)
85: {
86: var temp = node;
87:
88: while (temp != null && temp != thisnode) temp = temp.ParentNode;
89:
90: return temp != null;
91: }
92:
93: ////////////////////////////////////////////////////////////////////////////
94: ////////////////////////////////////////////////////////////////////////////
95:
96: /// <summary>
97: /// Pick a random value from List
98: ///<see href="http://stackoverflow.com/questions/2019417/access-random-item-in-list"/>
99: /// </summary>
100: public static T PickRandom<T>(this IEnumerable<T> source)
101: {
102: return source.PickRandom(1).Single();
103: }
104:
105: ////////////////////////////////////////////////////////////////////////////
106:
107: /// <summary>
108: ///
109: /// </summary>
110: public static IEnumerable<T> PickRandom<T>(this IEnumerable<T> source, int count)
111: {
112: return source.Shuffle().Take(count);
113: }
114:
115: ////////////////////////////////////////////////////////////////////////////
116:
117: /// <summary>
118: ///
119: /// </summary>
120: public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
121: {
122: return source.OrderBy(x => Guid.NewGuid());
123: }
124:
125: ////////////////////////////////////////////////////////////////////////////
126: ////////////////////////////////////////////////////////////////////////////
127:
128: /// <summary>
129: ///
130: /// </summary>
131: public static bool JustStartedOrRolledOver<T>(this IList<T> list)
132: {
133: return JustStarted(list) || RolledOver(list);
134: }
135:
136: ////////////////////////////////////////////////////////////////////////////
137:
138: /// <summary>
139: ///
140: /// </summary>
141: private static bool JustStarted<T>(this IList<T> list)
142: {
143: var listHashCode = list.GetHashCode();
144:
145: if (!listHashCodeToIndexDictionary.ContainsKey(listHashCode))
146: {
147: listHashCodeToIndexDictionary[listHashCode] = 0;
148: }
149:
150: return listHashCodeToIndexDictionary[listHashCode] == 0;
151: }
152:
153: ////////////////////////////////////////////////////////////////////////////
154:
155: /// <summary>
156: ///
157: /// </summary>
158: private static bool RolledOver<T>(this IList<T> list)
159: {
160: var listHashCode = list.GetHashCode();
161:
162: if (!listHashCodeToIndexDictionary.ContainsKey(listHashCode))
163: {
164: listHashCodeToIndexDictionary[listHashCode] = 0;
165: }
166:
167: return listHashCodeToIndexDictionary[listHashCode] % list.Count == 0;
168: }
169:
170: ////////////////////////////////////////////////////////////////////////////
171:
172: /// <summary>
173: ///
174: /// </summary>
175: public static T Next<T>(this IList<T> list)
176: {
177: var listHashCode = list.GetHashCode();
178:
179: if (!listHashCodeToIndexDictionary.ContainsKey(listHashCode))
180: {
181: listHashCodeToIndexDictionary[listHashCode] = 0;
182: }
183:
184: return list[listHashCodeToIndexDictionary[listHashCode]++ % list.Count];
185: }
186:
187: ////////////////////////////////////////////////////////////////////////////
188:
189: /// <summary>
190: ///
191: /// </summary>
192: public static T RandomThenNext<T>(this IList<T> list)
193: {
194: var listHashCode = list.GetHashCode();
195:
196: if (!listHashCodeToIndexDictionary.ContainsKey(listHashCode))
197: {
198: listHashCodeToIndexDictionary[listHashCode] = Ia.Cl.Model.Default.Random(list.Count);
199: }
200:
201: return list[listHashCodeToIndexDictionary[listHashCode]++ % list.Count];
202: }
203:
204: ////////////////////////////////////////////////////////////////////////////
205:
206: /// <summary>
207: ///
208: /// </summary>
209: public static T Next<T>(this IList<T> list, out int index, out int count)
210: {
211: var listHashCode = list.GetHashCode();
212:
213: if (!listHashCodeToIndexDictionary.ContainsKey(listHashCode))
214: {
215: listHashCodeToIndexDictionary[listHashCode] = 0;
216: }
217:
218: count = list.Count;
219: index = listHashCodeToIndexDictionary[listHashCode] % list.Count;
220:
221: var t = Next(list);
222:
223: return t;
224: }
225:
226: ////////////////////////////////////////////////////////////////////////////
227:
228: /// <summary>
229: ///
230: /// </summary>
231: public static T Next<T>(this IList<T> list, int index)
232: {
233: var i = index;
234:
235: return Next(list, ref i);
236: }
237:
238: ////////////////////////////////////////////////////////////////////////////
239:
240: /// <summary>
241: ///
242: /// </summary>
243: public static T Next<T>(this IList<T> list, ref int index, out int index2, out int count)
244: {
245: var listHashCode = list.GetHashCode();
246:
247: if (!listHashCodeToIndexDictionary.ContainsKey(listHashCode))
248: {
249: listHashCodeToIndexDictionary[listHashCode] = 0;
250: }
251:
252: count = list.Count;
253: index2 = index;
254:
255: var t = Next(list, ref index);
256:
257: return t;
258: }
259:
260: ////////////////////////////////////////////////////////////////////////////
261:
262: /// <summary>
263: ///
264: /// </summary>
265: public static T Next<T>(this IList<T> list, ref int index)
266: {
267: var listHashCode = list.GetHashCode();
268:
269: if (!listHashCodeToIndexDictionary.ContainsKey(listHashCode))
270: {
271: listHashCodeToIndexDictionary[listHashCode] = 0;
272: }
273:
274: if (index < 0 || index >= list.Count) throw new ArgumentOutOfRangeException("Index value: " + index + " is not within list range: 0," + (list.Count - 1));
275:
276: listHashCodeToIndexDictionary[listHashCode] = index;
277:
278: index = ++index % list.Count;
279:
280: return list[listHashCodeToIndexDictionary[listHashCode]++ % list.Count];
281: }
282:
283: ////////////////////////////////////////////////////////////////////////////
284:
285: /// <summary>
286: ///
287: /// </summary>
288: public static T NextOf<T>(this IList<T> list, T item)
289: {
290: return list[(list.IndexOf(item) + 1) == list.Count ? 0 : (list.IndexOf(item) + 1)];
291: }
292:
293: ////////////////////////////////////////////////////////////////////////////
294: ////////////////////////////////////////////////////////////////////////////
295:
296: /// <summary>
297: /// List get next element or get the first
298: ///<see href="https://stackoverflow.com/questions/22595655/how-to-do-a-dictionary-reverse-lookup"/>
299: /// </summary>
300: public static Dictionary<TValue, TKey> Reverse<TKey, TValue>(this IDictionary<TKey, TValue> source)
301: {
302: var dictionary = new Dictionary<TValue, TKey>();
303:
304: foreach (var entry in source)
305: {
306: if (entry.Value != null)
307: {
308: if (!dictionary.ContainsKey(entry.Value))
309: {
310: dictionary.Add(entry.Value, entry.Key);
311: }
312: }
313: }
314:
315: return dictionary;
316: }
317:
318: ////////////////////////////////////////////////////////////////////////////
319: ////////////////////////////////////////////////////////////////////////////
320:
321: public static IEnumerable<T> Flatten<T>(this T source, Func<T, IEnumerable<T>> selector)
322: {
323: // How to search Hierarchical Data with Linq
324: // https://stackoverflow.com/questions/18165460/how-to-search-hierarchical-data-with-linq
325:
326: return selector(source).SelectMany(c => Flatten(c, selector))
327: .Concat(new[] { source });
328: }
329:
330: ////////////////////////////////////////////////////////////////////////////
331: ////////////////////////////////////////////////////////////////////////////
332: }