我想通过正则表达式将IObservable<string>
转换为IObservable<int>
,我可以通过ToProperty
帮助器将其分配给属性。
public class MyViewModel : ReactiveObject
{
public MyViewModel {
var o = Observable.Create( .... );
o.Something(s => .... )
.ToProperty(this, x => x.Value, out _Value);
}
private ObservableAsPropertyHelper<int> _value;
public int Value { get { return _value.value; } }
}
第一个问题
什么是Something(s => ...)
的最佳替代品?
我想我可以使用Select(s => s.TryMatchRegex('regex'))
TryMatchRegex
返回int?
,然后使用Where(i => i.HasValue)
然后使用新Select(i => i.Value)
,但我发现它并不聪明。 ..
第二个问题
现在,想象一下我有几个正则表达式。每个发布的值可以匹配这些正则数据中的零个或多个。每个正则表达式都有相应的属性。我需要多次订阅源代码,还是有更好的方法呢?
答案 0 :(得分:3)
我认为你可能过分思考了。您建议的所有内容听起来都合理,并且会在第一个实例中生成易于遵循的代码。您可以将正则表达式投影+过滤逻辑包装到具有有意义名称的自定义运算符中,以最大限度地提高可读性。
在优化之前检查性能是否有问题。明显的优化(如果需要)包括:
DistinctUntilChanged().Publish().RefCount()
上应用o
并订阅您的正则表达式投影< / LI>
答案 1 :(得分:3)
SelectMany
查询可能是最好的,因为您可以使用内部IEnumerable<T>
来表示零个或多个匹配。
或者,您可以Publish
来源hot
,这样您就可以为每个属性编写单独的查询,而不必担心重复订阅副作用,但除非您计划引入并行自己并行执行它们,正则表达式无论如何都要串行应用;因此,最好只在一次投影中将它们组合在一起。
我可能只是在Rx中使用本地定义的BehaviorSubject<T>
。我不确定ToProperty
提供什么。
例如(未经测试):
public class MyViewModel
{
public int X
{
get { return x.Value; }
private set { x.OnNext(value); }
}
public int Y
{
get { return y.Value; }
private set { y.OnNext(value); }
}
public int Z
{
get { return z.Value; }
private set { z.OnNext(value); }
}
private readonly BehaviorSubject<int> x = new BehaviorSubject<int>(0);
private readonly BehaviorSubject<int> y = new BehaviorSubject<int>(0);
private readonly BehaviorSubject<int> z = new BehaviorSubject<int>(0);
public MyViewModel(IObservable<string> source)
{
var patterns = new Dictionary<string, IObserver<int>>()
{
{ patternX, x },
{ patternY, y },
{ patternZ, z }
};
(from input in source
from action in from pattern in patterns
let match = Regex.Match(input, pattern.Key)
where match.Success
let value = GetInt32Somehow(match.Value)
select new Action(() => pattern.Value.OnNext(value))
select action)
.Subscribe(action => action());
}
}