我有一個具有各種屬性的.NET對象的集合。讓我們說它是一個遺傳密碼中的染色體鏈 - 儘管對象數據比這更復雜一點。我想在列表中搜索預定義的對象序列。我可以將對象定義爲有限數量的獨特感興趣類型。 R,B,d和一個巨大的名單,我想找到對象的特定序列:.NET對象列表中的正則表達式樣式匹配
一個大規模簡化版本是:
public class Chromosome {
public ChromosomeType CromosomeType {
get {
// Some logic that works out and returns the correct chromosome type
}
}
}
public enum ChromosomeType {
R, B, D
}
所以給大集合這些類型。我想匹配某些序列
例如, "R+B{3}D+"
所以在「正則表達式」以上,以下序列將在列表中匹配: RRRBBBDD
我需要能夠從一個很長的對象列表返回所有比賽。
顯然,正則表達式對此非常完美,但我實際上並沒有字符串,我有對象集合。
什麼是預定義序列搜索對象集合的最佳方法?
更新
科林的解決方案是我最後一個解決方案。它效果很好。我更新了它能夠處理多個匹配,並使用數組中爲了儘可能快地
下面是最終有效的解決方案:
public static class ChromosomesExtensions
{
public static IEnumerable<Chromosome[]> FindBySequence(this Chromosome[] chromosomes, string patternRegex)
{
var sequenceString
= String.Join(
String.Empty, //no separator
(
from c in chromosomes
select c.CromosomeType.ToString()
)
);
MatchCollection matches = Regex.Matches(sequenceString, patternRegex);
foreach (Match match in matches)
{
Chromosome[] subset = new Chromosome[match.Value.Length];
var j = 0;
for (var i = match.Index; i < match.Index + match.Length; i++)
{
subset[j++] = chromosomes[i];
}
yield return subset;
}
}
}
[TestFixture]
public class TestClass
{
[Test]
public void TestMethod()
{
var chromosomes =
new[]
{
new Chromosome(){ CromosomeType = ChromosomeType.D, Id = 1},
new Chromosome(){ CromosomeType = ChromosomeType.R, Id = 2 },
new Chromosome(){ CromosomeType = ChromosomeType.R, Id = 3 },
new Chromosome(){ CromosomeType = ChromosomeType.B, Id = 4 },
new Chromosome(){ CromosomeType = ChromosomeType.B, Id = 5 },
new Chromosome(){ CromosomeType = ChromosomeType.B, Id = 6 },
new Chromosome(){ CromosomeType = ChromosomeType.D, Id = 7 },
new Chromosome(){ CromosomeType = ChromosomeType.D, Id = 8 },
new Chromosome(){ CromosomeType = ChromosomeType.B, Id = 9 },
new Chromosome(){ CromosomeType = ChromosomeType.R, Id = 10 },
new Chromosome(){ CromosomeType = ChromosomeType.R, Id = 11 },
new Chromosome(){ CromosomeType = ChromosomeType.B, Id = 12 },
new Chromosome(){ CromosomeType = ChromosomeType.B, Id = 13 },
new Chromosome(){ CromosomeType = ChromosomeType.B, Id = 14 },
new Chromosome(){ CromosomeType = ChromosomeType.D, Id = 15 },
new Chromosome(){ CromosomeType = ChromosomeType.D, Id = 16 },
new Chromosome(){ CromosomeType = ChromosomeType.R, Id = 17 },
new Chromosome(){ CromosomeType = ChromosomeType.R, Id = 18 },
new Chromosome(){ CromosomeType = ChromosomeType.B, Id = 19 },
new Chromosome(){ CromosomeType = ChromosomeType.B, Id = 20 },
new Chromosome(){ CromosomeType = ChromosomeType.B, Id = 21 },
new Chromosome(){ CromosomeType = ChromosomeType.D, Id = 22 },
new Chromosome(){ CromosomeType = ChromosomeType.D, Id = 23 },
};
var matchIndex = 0;
foreach (Chromosome[] match in chromosomes.FindBySequence("R+B{3}D+"))
{
Console.WriteLine($"Match {++matchIndex}");
var result = new String(match.SelectMany(x => string.Join("", $"id: {x.Id} Type: {x.CromosomeType.ToString()}\n")).ToArray());
Console.WriteLine(result);
}
}
}
輸出:
Match 1
id: 2 Type: R
id: 3 Type: R
id: 4 Type: B
id: 5 Type: B
id: 6 Type: B
id: 7 Type: D
id: 8 Type: D
Match 2
id: 10 Type: R
id: 11 Type: R
id: 12 Type: B
id: 13 Type: B
id: 14 Type: B
id: 15 Type: D
id: 16 Type: D
Match 3
id: 17 Type: R
id: 18 Type: R
id: 19 Type: B
id: 20 Type: B
id: 21 Type: B
id: 22 Type: D
id: 23 Type: D
我不是很清楚。是否有一個屬性保存了您匹配的值,或者您想對類型名稱本身應用正則表達式。你能用你的對象結構更新問題嗎? – niksofteng
假設我的理解正確,你可以重寫'ToString()'來讓它返回,無論這個特定對象是R,B還是D.然後,爲整個鏈建立一個字符串,然後在你的'Regex'上執行那。 – AntiTcb
你的對象的例子會有所幫助。 – DVK