Skip to content

Commit a51b082

Browse files
committed
update: added new functionality to SwiftExtensions and HashHelper
1 parent 517ce56 commit a51b082

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

src/SwiftCollections/Utilities/HashHelper.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,5 +187,32 @@ private static uint FMix(uint h)
187187
h ^= h >> 16;
188188
return h;
189189
}
190+
191+
// System.String.GetHashCode(): http://referencesource.microsoft.com/#mscorlib/system/string.cs,0a17bbac4851d0d4
192+
// System.Web.Util.StringUtil.GetStringHashCode(System.String): http://referencesource.microsoft.com/#System.Web/Util/StringUtil.cs,c97063570b4e791a
193+
public static int CombineHashCodes(
194+
this ITuple tupled,
195+
int seed = 5381,
196+
int shift1 = 16,
197+
int shift2 = 5,
198+
int shift3 = 27,
199+
int factor3 = 1566083941)
200+
{
201+
int hash1 = (seed << shift1) + seed;
202+
int hash2 = hash1;
203+
204+
for (int i = 0; i < tupled.Length; i++)
205+
{
206+
unchecked
207+
{
208+
if (i % 2 == 0)
209+
hash1 = ((hash1 << shift2) + hash1 + (hash1 >> shift3)) ^ tupled[i].GetHashCode();
210+
else
211+
hash2 = ((hash2 << shift2) + hash2 + (hash2 >> shift3)) ^ tupled[i].GetHashCode();
212+
}
213+
}
214+
215+
return hash1 + (hash2 * factor3);
216+
}
190217
}
191218
}

src/SwiftCollections/Utilities/SwiftExtensions.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,5 +157,41 @@ public static bool IsPopulated<T>(this IEnumerable<T> source)
157157
/// </returns>
158158
[MethodImpl(MethodImplOptions.AggressiveInlining)]
159159
public static bool IsPopulatedSafe<T>(this IEnumerable<T> source) => source != null && source.IsPopulated();
160+
161+
/// <summary>
162+
/// Gets the element at the specified index from the end (1-based).
163+
/// For example, FromEnd(1) returns the last item, FromEnd(2) returns second-to-last.
164+
/// </summary>
165+
public static T FromEnd<T>(this IEnumerable<T> source, int reverseIndex)
166+
{
167+
if (source is SwiftList<T> swift)
168+
return swift.FromEnd(reverseIndex);
169+
170+
// fallback for generic IEnumerable
171+
var buffer = new List<T>(source);
172+
return buffer.FromEnd(reverseIndex);
173+
}
174+
175+
/// <summary>
176+
/// Gets the element at the specified index from the end (1-based) from SwiftList.
177+
/// </summary>
178+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
179+
public static T FromEnd<T>(this SwiftList<T> list, int reverseIndex)
180+
{
181+
if (reverseIndex <= 0 || reverseIndex > list.Count)
182+
throw new ArgumentOutOfRangeException(nameof(reverseIndex));
183+
return list[list.Count - reverseIndex];
184+
}
185+
186+
/// <summary>
187+
/// Returns the last item in the sequence.
188+
/// </summary>
189+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
190+
public static T Last<T>(this IEnumerable<T> source) => source.FromEnd(1);
191+
192+
/// <summary>
193+
/// Returns the second-to-last item in the sequence.
194+
/// </summary>
195+
public static T SecondToLast<T>(this IEnumerable<T> source) => source.FromEnd(2);
160196
}
161197
}

0 commit comments

Comments
 (0)