我不知道是否太晚了,但我有一个答案给你。
您需要使用的Rx扩展方法是BufferWithCount
。
我假设你知道如何将按键事件转换为IObservable<char>
。
所以给你,你要检测,然后执行我建议使用一个Dictionary<string, Action>
来保存这些数据,像这样一个动作字符序列的列表:
var matches = new Dictionary<string, Action>()
{
{ "ba",() => Console.WriteLine("ba") },
{ "aba",() => Console.WriteLine("aba") },
{ "baa",() => Console.WriteLine("baa") },
{ "abc\t",() => Console.WriteLine("abc\\t") },
};
因此,这里的的Rx(和IEnumerable
需要)查询:
int max =
matches
.Select(m => m.Key.Length)
.Max();
IObservable<string> chords =
Enumerable
.Range(2, max - 1)
.Select(n => keys
.BufferWithCount(n, 1)
.Select(cs => new string(cs.ToArray())))
.Merge();
IObservable<Action> actions =
chords
.Where(s => matches.ContainsKey(s))
.Select(s => matches[s]);
所以最后你只是有一个IObservable<Action>
,你可以订阅,您只需调用Action
。
如果你想测试一下这个工程使用下面的代码:
IConnectableObservable<char> keys = "ababc\tdabaababc\tebad"
.ToObservable()
.Publish();
//`.Publish()` makes a cold observable become hot,
// but you must call `Connect()` to start producing values.
//insert above `matches` definition here.
//insert above queries here.
actions.Subscribe(a => a());
keys.Connect();
结果应该是:
ba
aba
abc\t
ba
aba
baa
ba
aba
abc\t
ba
享受!
太棒了!谢谢! – 2010-12-08 13:15:51