我有一個Array
字節,表示圖像的RGB值。使用Linq將三個數組的項目分組爲
如何將這個數組的3個值(RGB)的每個偏移量分組來應用我的調整(如去除重複的顏色),也許使用Linq?
["120", "100", "10", "120", "100", "10", "10", "60", "110"]
到
["120", "100", "10", "10", "60", "110"]
我有一個Array
字節,表示圖像的RGB值。使用Linq將三個數組的項目分組爲
如何將這個數組的3個值(RGB)的每個偏移量分組來應用我的調整(如去除重複的顏色),也許使用Linq?
["120", "100", "10", "120", "100", "10", "10", "60", "110"]
到
["120", "100", "10", "10", "60", "110"]
可以使用Select
通過index/3
索引添加到您的枚舉和後組。對每個組進行一些後處理,你應該可以得到你想要的:
var grouped = source.Select((x,i) => new { x, i })
.GroupBy(x -> x.i/3)
.Select(g => g.ToList())
.Select(g => new { R = g[0], G = g[1], B = g[2] })
.Distinct();
但是,這感覺相當醜陋。如果我是你,我可能會寫一個簡單的自定義LINQ方法(IEnumerable<int>
上的擴展方法)來更有效地執行此操作。
如果你不介意使用一個循環,而不是LINQ的:
class Program
{
static void Main(string[] args)
{
byte[] array = new byte[] { 120, 100, 10, 120, 100, 10, 10, 60, 110 };
List<byte[]> grouped = new List<byte[]>();
// This loop will populate the list grouped with arrays of 3 bytes each, each representing an value for RGB
for(int i = 0; i + 2 < array.Length; i += 3)
{
byte[] currentColor = new byte[]
{
array[i],
array[i + 1],
array[i + 2]
};
grouped.Add(currentColor);
}
// Here you will remove repeated elements for RGB
// Notice you will have to create the ByteArrayComparer class, you will find the code right under this one
var noRepeatedElements = grouped.Distinct<byte[]>(new ByteArrayComparer());
// Print the non repeated elements for testing purposes
foreach(var rgb in noRepeatedElements)
{
foreach(var value in rgb)
{
Console.Write($"\"{value}\"");
}
}
Console.ReadKey();
}
}
哪裏ByteArrayComparer是下面的類
// This class will compare two distinct byte arrays and check if their elements are the same
public class ByteArrayComparer : IEqualityComparer<byte[]>
{
public bool Equals(byte[] x, byte[] y)
{
int smallerArrayLength = Math.Min(x.Length, y.Length);
bool elementsWithSameValue = true;
for(int i = 0; i < smallerArrayLength; i++)
{
// If there is a single element which is different, we know the arrays are different and can break the loop.
if(x[i] != y[i])
{
elementsWithSameValue = false;
break;
}
}
return elementsWithSameValue;
}
public int GetHashCode(byte[] obj)
{
int hash = 0;
for(int i = 0; i < obj.Length; i++)
{
hash += obj[i].GetHashCode();
}
return hash;
}
}
注意分組現在是一個字節數組列表。 中的每個元素分組爲有三個元素,表示單個RGB值。
現在您可以隨心所欲地使用rgb值。
較短的版本是可以獲得不同的RGB值及其索引:
string[] a = { "120", "100", "10", "120", "100", "10", "10", "60", "110" };
var l = Enumerable.Range(0, a.Length/3)
.ToLookup(i => new { R = a[i * 3], G = a[i * 3 + 1], B = a[i * 3 + 2] });
使用微軟的無框架小組的互動擴展(的NuGet 「IX-主」),你可以這樣做:
byte[] array = new byte[]
{
120, 100, 10, 120, 100, 10, 10, 60, 110
};
byte[] results =
array
.Buffer(3)
.Distinct(xs => String.Join(",", xs))
.SelectMany(x => x)
.ToArray();
那會給你{ 120, 100, 10, 10, 60, 110 }
。
這顯示了不同的方式來分塊列表:http://stackoverflow.com/questions/419019/split-list-into-sublists-with-linq – hdz
你可以使用Skeet的[morelinq庫](https:// github .com/morelinq/MoreLINQ)及其「Batch」方法。 –