|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
|
|
|
|
namespace ZeroLevel
|
|
|
|
|
{
|
|
|
|
|
public static class ArrayExtensions
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Deep copy array
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static T[] DeepCopy<T>(this T[] array)
|
|
|
|
|
where T : ICloneable
|
|
|
|
|
{
|
|
|
|
|
return array.Select(a => (T)a.Clone()).ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Copyright (c) 2008-2013 Hafthor Stefansson
|
|
|
|
|
// Distributed under the MIT/X11 software license
|
|
|
|
|
// Ref: http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
public static unsafe bool UnsafeEquals(byte[] first, byte[] second)
|
|
|
|
|
{
|
|
|
|
|
if (null == first && null == second)
|
|
|
|
|
return true;
|
|
|
|
|
if (null == first || null == second)
|
|
|
|
|
return false;
|
|
|
|
|
if (ReferenceEquals(first, second))
|
|
|
|
|
return true;
|
|
|
|
|
if (first.Length != second.Length) return false;
|
|
|
|
|
fixed (byte* p1 = first, p2 = second)
|
|
|
|
|
{
|
|
|
|
|
byte* x1 = p1, x2 = p2;
|
|
|
|
|
int l = first.Length;
|
|
|
|
|
for (int i = 0; i < l / 8; i++, x1 += 8, x2 += 8)
|
|
|
|
|
if (*((long*)x1) != *((long*)x2)) return false;
|
|
|
|
|
if ((l & 4) != 0) { if (*((int*)x1) != *((int*)x2)) return false; x1 += 4; x2 += 4; }
|
|
|
|
|
if ((l & 2) != 0) { if (*((short*)x1) != *((short*)x2)) return false; x1 += 2; x2 += 2; }
|
|
|
|
|
if ((l & 1) != 0) if (*((byte*)x1) != *((byte*)x2)) return false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Checks whether one array is in another
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static bool Contains<T>(this T[] array, T[] candidate)
|
|
|
|
|
{
|
|
|
|
|
if (IsEmptyLocate(array, candidate))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
for (int a = 0; a < array.Length; a++)
|
|
|
|
|
{
|
|
|
|
|
if (array[a]!.Equals(candidate[0]))
|
|
|
|
|
{
|
|
|
|
|
int i = 1;
|
|
|
|
|
for (; i < candidate.Length && (a + i) < array.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
if (false == array[a + i]!.Equals(candidate[i]))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (i == candidate.Length)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static bool IsEmptyLocate<T>(this T[] array, T[] candidate)
|
|
|
|
|
{
|
|
|
|
|
return array == null
|
|
|
|
|
|| candidate == null
|
|
|
|
|
|| array.Length == 0
|
|
|
|
|
|| candidate.Length == 0
|
|
|
|
|
|| candidate.Length > array.Length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static IEnumerable<T> GetRow<T>(this T[,] array, int row)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < array.GetLength(1); i++)
|
|
|
|
|
{
|
|
|
|
|
yield return array[row, i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static IEnumerable<T> GetColumn<T>(this T[,] array, int column)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < array.GetLength(0); i++)
|
|
|
|
|
{
|
|
|
|
|
yield return array[i, column];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static bool Equals(byte[] first, byte[] second)
|
|
|
|
|
{
|
|
|
|
|
if (null == first && null == second)
|
|
|
|
|
return true;
|
|
|
|
|
if (null == first || null == second)
|
|
|
|
|
return false;
|
|
|
|
|
if (ReferenceEquals(first, second))
|
|
|
|
|
return true;
|
|
|
|
|
if (first.Length != second.Length) return false;
|
|
|
|
|
for (int i = 0; i < first.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
if (first[i] != second[i]) return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|