Related
I am trying to use reactive operators to find individual sum of the values emitted by the observable. The end goal is to emit individual sums. The sequence looks something like this. The ones I want to add up are occuring as continuous groups (of varying length) with varying frequency in between the values I want to discard. The ones I want to add have a field which is of type bool and has value true.
-(F,2)-(T,4)-(T,2)-(T,7)-(F,8)-(F,9)-(F,1)-(T,2)-(T,1)-(F,1)-
What have I tried so far:
myObservable.
.Where(x => x.IsItUseful == true)
.Aggregate(0.0, (sum,currentItem) => sum + currentItem.Value)
.Subscribe("NotYet")
This one give back the sum of ALL elements which have been marked as true.
myObservable
.SkipWhile(x => x.IsItUseful == false)
.TakeWhile(x => x.IsItUseful == true)
.Aggregate(0.0, (sum, currentItem) => sum + currentItem.Item3)
.Subscribe("NotYetAgain");
This one gives the sum of the first group only.
Right now I am trying along these lines.
myObservable
.Buffer(myObservable.DistinctUntilChanged(x => x.IsItUseful => true)
.Subscribe("NotSure")
I am still hazy on on BufferBoundary and BufferClosingSelector. I think a new buffer will open once I process a group of valid values. And this new buffer will have values from that point on wards till the end of another valid group. This means that I will pick up some not valid values too before the second group. I haven't been able to find some examples on Buffer with both open and close options getting used. Not sure if this is right approach too.
The final option is that I write an extension method on Buffer and put my custom logic there. But if there is an out of box solution I will prefer that.
There's two primary approaches I would recommend here. One uses Scan, the other uses Buffer/Window. Both of them have edge case problems that are solvable, but need clarity on the problem side.
Here's the Scan solution:
var result = source
.Scan((0, true), (state, value) => (value.IsItUseful ? state.Item1 + value.Value : 0, value.IsItUseful))
.Publish(_tuples =>
_tuples.Zip(_tuples.Skip(1), (oldTuple, newTuple) => (oldTuple, newTuple))
)
.Where(t => t.oldTuple.Item2 == true && t.newTuple.Item2 == false)
.Select(t => t.oldTuple.Item1);
Scan is similar to Aggregate, just more useful: Aggregate will only dump out one value at the end; whereas Scan emits intermediate values. So we track the running sum in there, resetting to 0 when we see a false. The next step (Zip) combines the latest message with its predecessor, so we can figure out whether or not we have to emit: We want to emit if the new flag value is false, but the old flag value is true. We then emit the old sum.
There's an edge case problem here if the last flag value is true: I'm assuming you want to emit on the OnCompleted, but that won't currently happen. Please clarify if that's needed.
Here's the Window solution:
var result2 = source
.Publish(_values => _values
.Window(_values.Select(v => v.IsItUseful).DistinctUntilChanged().Where(b => b == false))
)
.SelectMany(o => o.Where(a => a.IsItUseful).Sum(a => a.Value));
Window by the distinctly new falses, then sum them, similar to what you proposed.
The edge case problem here is that you end up with a leading and tailing 0 if you begin/end with falses (as your sample set does). Removing those would require some clean up as well.
FYI: Window and Buffer are practically the same: They have the same overloads and each group values into "windows". Window returns them as an observable stream, and Buffer holds them into a list which returns when the window closes. For more look here.
Here's runner code if anybody else wants to test this:
public class Message
{
public Message(bool b, int v)
{
IsItUseful = b;
Value = v;
}
public bool IsItUseful { get; set; }
public int Value { get; set; }
}
var values = new List<Message>
{
new Message(false, 2),
new Message(true, 4),
new Message(true, 2),
new Message(true, 7),
new Message(false, 8),
new Message(false, 9),
new Message(false, 1),
new Message(true, 2),
new Message(true, 1),
new Message(false, 1),
};
var source = values.ToObservable();
var result = source
.Scan((0, true), (state, value) => (value.IsItUseful ? state.Item1 + value.Value : 0, value.IsItUseful))
.Publish(_tuples =>
_tuples.Zip(_tuples.Skip(1), (oldTuple, newTuple) => (oldTuple, newTuple))
)
.Where(t => t.oldTuple.Item2 == true && t.newTuple.Item2 == false)
.Select(t => t.oldTuple.Item1);
var result2 = source
.Publish(_values => _values
.Buffer(_values.Select(v => v.IsItUseful).DistinctUntilChanged().Where(b => b == false))
)
.Select(o => o.Where(a => a.IsItUseful).Sum(a => a.Value));
result.Dump(); //Linqpad
result2.Dump(); //Linqpad
I'm struggling with the evaluation of checkBoxesFieldList of monadic forms in my Yesod appliction.
I'm using these to create n-questions where n is the number of checkBoxesFieldList, with 4 answers (only True/False) each. But in comparison to the applicative forms, these already "evaluate" the result and tell me if I answered correctly.
The problem occurs if there are boxes unchecked, or you check a wrong one out of four, so I can't know what wrong answer you checked.
Example:
If I checked only the first box, the result is [False].
If I checked only the second box wrong, the result is still [False].
If I checked only the third box (but it was the right answer), the result is [True].
What I want to achieve: The result from runFormPost should give me a [Bool] based on: checked -> return True, unchecked -> return False.
Example:
If I checked only the first box wrong, the result should be [True, False, False, False]
I already had to customize the checkboxesField from the library, but I just can't find a way remove the evaluation.
Here is the code:
data Question = Question {
, identity :: Text
, content :: Text
, answerList :: [Answer]
, maxScore :: Int
}
data Answer = Answer {
, identity :: Text
, content :: Text
, isCorrect :: Bool
, hint :: Text
}
zipAnswers :: [Answer] -> [(Text, Bool)]
zipAnswers [] = []
zipAnswers ((Answer _ text val _):xs) = (text, val):zipAnswers xs
listEditMForm :: [Question] -> Html -> MForm Handler (FormResult ([FormResult (Maybe [Bool])]), Widget)
listEditMForm xs token = do
check_fields <- forM xs (\(Question _ content alist _ ) -> mopt (checkboxesFieldList' $ zipAnswers alist) (fromString $ T.unpack content) Nothing)
let (check_results, check_views) = unzip check_fields
let numerated_views = zip ([1..]::[Int]) check_views
let widget = [whamlet|
^{token}
<ul class="tabs">
$forall (c,view) <- numerated_views
<li>
<input type="radio" name="tabs" id="tab#{fvId view}">
<label for="tab#{fvId view}">Q #{show c}
<div id="tab-content#{fvId view}" class="tab-content animated fadeIn">
<p class=boldWhite> #{fvLabel view}: </p>
^{fvInput view}
<br>
<input class=button type=submit value="Testing">
|]
return ((FormSuccess check_results), widget)
checkboxesFieldList' :: (Eq a, RenderMessage site FormMessage, RenderMessage site msg) => [(msg, a)]
-> Field (HandlerT site IO) [a]
checkboxesFieldList' = checkboxesField' . optionsPairs
checkboxesField' :: (Eq a, RenderMessage site FormMessage)
=> HandlerT site IO (OptionList a)
-> Field (HandlerT site IO) [a]
checkboxesField' ioptlist = (multiSelectField ioptlist)
{ fieldView =
\theId name attrs val _ -> do
opts <- fmap olOptions $ handlerToWidget ioptlist
let optselected (Left _) _ = False
optselected (Right vals) opt = (optionInternalValue opt) `elem` vals
[whamlet|
<span ##{theId}>
$forall opt <- opts
<label>
<input type=checkbox name=#{name} value=#{optionExternalValue opt} *{attrs} :optselected val opt:checked>
<span class=simpleWhite> #{optionDisplay opt}
|]
}
The code block below answers the question: "How do you perform a left outer join using linq extension methods?"
var qry = Foo.GroupJoin(
Bar,
foo => foo.Foo_Id,
bar => bar.Foo_Id,
(x,y) => new { Foo = x, Bars = y })
.SelectMany(
x => x.Bars.DefaultIfEmpty(),
(x,y) => new { Foo = x, Bar = y});
How do you write this GroupJoin and SelectMany as MethodCallExpressions? All of the examples that I've found are written using DynamicExpressions translating strings into lambdas (another example). I like to avoid taking a dependency on that library if possible.
Can the query above be written with Expressions and associated methods?
I know how to construct basic lambda expressions like foo => foo.Foo_Id using ParameterExpressions MemberExpressions and Expression.Lambda() , but how do you construct (x,y) => new { Foo = x, Bars = y })??? to be able to construct the necessary parameters to create both calls?
MethodCallExpression groupJoinCall =
Expression.Call(
typeof(Queryable),
"GroupJoin",
new Type[] {
typeof(Customers),
typeof(Purchases),
outerSelectorLambda.Body.Type,
resultsSelectorLambda.Body.Type
},
c.Expression,
p.Expression,
Expression.Quote(outerSelectorLambda),
Expression.Quote(innerSelectorLambda),
Expression.Quote(resultsSelectorLambda)
);
MethodCallExpression selectManyCall =
Expression.Call(typeof(Queryable),
"SelectMany", new Type[] {
groupJoinCall.ElementType,
resultType,
resultsSelectorLambda.Body.Type
}, groupJoinCall.Expression, Expression.Quote(lambda),
Expression.Quote(resultsSelectorLambda)));
Ultimately, I need to create a repeatable process that will left join n Bars to Foo. Because we have a vertical data structure, a left-joined query is required to return what is represented as Bars, to allow the user to sort Foo. The requirement is to allow the user to sort by 10 Bars, but I don't expect them to ever use more than three. I tried writing a process that chained the code in the first block above up to 10 times, but once I got passed 5 Visual Studio 2012 start to slow and around 7 it locked up.
Therefore, I'm now trying to write a method that returns the selectManyCall and calls itself recursively as many times as is requested by the user.
Based upon the query below that works in LinqPad, the process that needs to be repeated only requires manually handling the transparent identifiers in Expression objects. The query sorts returns Foos sorted by Bars (3 Bars in this case).
A side note. This process is significantly easier doing the join in the OrderBy delegate, however, the query it produces includes the T-SQL "OUTER APPLY", which isn't supported by Oracle which is required.
I'm grateful for any ideas on how to write the projection to anonymous type or any other out-of-the-box idea that may work. Thank you.
var q = Foos
.GroupJoin (
Bars,
g => g.FooID,
sv => sv.FooID,
(g, v) =>
new
{
g = g,
v = v
}
)
.SelectMany (
s => s.v.DefaultIfEmpty (),
(s, v) =>
new
{
s = s,
v = v
}
)
.GroupJoin (
Bars,
g => g.s.g.FooID,
sv => sv.FooID,
(g, v) =>
new
{
g = g,
v = v
}
)
.SelectMany (
s => s.v.DefaultIfEmpty (),
(s, v) =>
new
{
s = s,
v = v
}
)
.GroupJoin (
Bars,
g => g.s.g.s.g.FooID,
sv => sv.FooID,
(g, v) =>
new
{
g = g,
v = v
}
)
.SelectMany (
s => s.v.DefaultIfEmpty (),
(s, v) =>
new
{
s = s,
v = v
}
)
.OrderBy (a => a.s.g.s.g.v.Text)
.ThenBy (a => a.s.g.v.Text)
.ThenByDescending (a => a.v.Date)
.Select (a => a.s.g.s.g.s.g);
If you're having trouble figuring out how to generate the expressions, you could always get an assist from the compiler. What you could do is declare an lambda expression with the types you are going to query with and write the lambda. The compiler will generate the expression for you and you can examine it to see what expressions make up the expression tree.
e.g., your expression is equivalent to this using the query syntax (or you could use the method call syntax if you prefer)
Expression<Func<IQueryable<Foo>, IQueryable<Bar>, IQueryable>> expr =
(Foo, Bar) =>
from foo in Foo
join bar in Bar on foo.Foo_Id equals bar.Foo_Id into bars
from bar in bars.DefaultIfEmpty()
select new
{
Foo = foo,
Bar = bar,
};
To answer your question, you can't really generate an expression that creates an anonymous object, the actual type isn't known at compile time. You can cheat kinda by creating a dummy object and use GetType() to get its type which you could then use to create the appropriate new expression, but that's more of a dirty hack and I wouldn't recommend doing this. Doing so, you won't be able to generate strongly typed expressions since you don't know the type of the anonymous type.
e.g.,
var dummyType = new
{
foo = default(Foo),
bars = default(IQueryable<Bar>),
}.GetType();
var fooExpr = Expression.Parameter(typeof(Foo), "foo");
var barsExpr = Expression.Parameter(typeof(IQueryable<Bar>), "bars");
var fooProp = dummyType.GetProperty("foo");
var barsProp = dummyType.GetProperty("bars");
var ctor = dummyType.GetConstructor(new Type[]
{
fooProp.PropertyType,
barsProp.PropertyType,
});
var newExpr = Expression.New(
ctor,
new Expression[] { fooExpr, barsExpr },
new MemberInfo[] { fooProp, barsProp }
);
// the expression type is unknown, just some lambda
var lambda = Expression.Lambda(newExpr, fooExpr, barsExpr);
Whenever you need to generate an expression that involves an anonymous object, the right thing to do would be to create an known type and use that in place of the anonymous type. It will have limited use yes but it's a much cleaner way to handle such a situation. Then at least you'll be able to get the type at compile time.
// use this type instead of the anonymous one
public class Dummy
{
public Foo foo { get; set; }
public IQueryable<Bar> bars { get; set; }
}
var dummyType = typeof(Dummy);
var fooExpr = Expression.Parameter(typeof(Foo), "foo");
var barsExpr = Expression.Parameter(typeof(IQueryable<Bar>), "bars");
var fooProp = dummyType.GetProperty("foo");
var barsProp = dummyType.GetProperty("bars");
var ctor = dummyType.GetConstructor(Type.EmptyTypes);
var newExpr = Expression.MemberInit(
Expression.New(ctor),
Expression.Bind(fooProp, fooExpr),
Expression.Bind(barsProp, barsExpr)
);
// lambda's type is known at compile time now
var lambda = Expression.Lambda<Func<Foo, IQueryable<Bar>, Dummy>>(
newExpr,
fooExpr,
barsExpr);
Or, instead of creating and using a dummy type, you might be able to use tuples in your expressions instead.
static Expression<Func<T1, T2, Tuple<T1, T2>>> GetExpression<T1, T2>()
{
var type1 = typeof(T1);
var type2 = typeof(T2);
var tupleType = typeof(Tuple<T1, T2>);
var arg1Expr = Expression.Parameter(type1, "arg1");
var arg2Expr = Expression.Parameter(type2, "arg2");
var arg1Prop = tupleType.GetProperty("Item1");
var arg2Prop = tupleType.GetProperty("Item2");
var ctor = tupleType.GetConstructor(new Type[]
{
arg1Prop.PropertyType,
arg2Prop.PropertyType,
});
var newExpr = Expression.New(
ctor,
new Expression[] { arg1Expr, arg2Expr },
new MemberInfo[] { arg1Prop, arg2Prop }
);
// lambda's type is known at compile time now
var lambda = Expression.Lambda<Func<T1, T2, Tuple<T1, T2>>>(
newExpr,
arg1Expr,
arg2Expr);
return lambda;
}
Then to use it:
var expr = GetExpression<Foo, IQueryable<Bar>>();
I have two value streams and one selector stream and I'd like to produce a result stream that alternates between the value streams based on the selector. The code below gives the right result, but I don't like it.
Does anyone have anything neater?
var valueStreamA = new BehaviorSubject<int>(0);
var valueStreamB = new BehaviorSubject<int>(100);
var selectorStream = new BehaviorSubject<bool>(true);
var filteredA = valueStreamA .CombineLatest(selectorStream, (a, c) => new { A = a, C = c })
.Where(ac => ac.C)
.Select(ac => ac.A);
var filteredB = valueStreamB.CombineLatest(selectorStream, (b, c) => new { B = b, C = c })
.Where(bc => !bc.C)
.Select(bc => bc.B);
var result = Observable.Merge(filteredA, filteredB);
result.Subscribe(Console.WriteLine);
valueStreamA.OnNext(1);
valueStreamB.OnNext(101);
selectorStream.OnNext(false);
valueStreamA.OnNext(2);
valueStreamB.OnNext(102);
selectorStream.OnNext(true);
This productes the following output:
0
1
101
102
2
I'd do something like this:
var a = new BehaviorSubject<int>(0);
var b = new BehaviorSubject<int>(100);
var c = new BehaviorSubject<bool>(true);
var valueStreamA = a as IObservable<int>;
var valueStreamB = b as IObservable<int>;
var selector = c as IObservable<bool>;
var result = selector
// for every change in the selector...
.DistinctUntilChanged()
// select one of the two value streams
.Select(change => change ? valueStreamA : valueStreamB)
// and flatten the resulting wrapped observable
.Switch();
result.Subscribe(Console.WriteLine);
a.OnNext(1);
b.OnNext(101);
c.OnNext(false);
a.OnNext(2);
b.OnNext(102);
c.OnNext(true);
Could do something like:
var xs = Observable.Interval(TimeSpan.FromSeconds(1)).Select(_ => Feeds.Xs);
var ys = Observable.Interval(TimeSpan.FromSeconds(1)).Select(_ => Feeds.Ys);
var selectorSubject = new Subject<Feeds>();
var query = from selector in selectorSubject
select from merged in xs.Merge(ys)
where merged == selector
select merged;
query.Switch().Subscribe(Console.WriteLine);
OnNext into your 'selectorSubject' to change it.
There are a few differences to your example, but easy to get around:
Your question involved a selector of type bool, whereas I have been lazy and reused the Feeds enum in order to allow me to do an easy equality check (where merged == selector).
You of course could simply do (where selector ? merged == Xs : merged == Ys), or something like that to evaluate each merged item and discard ones you don't care about (depending on your selector).
Specifically, you would probably want to select not just the integer, but an identifier of the feed. Consider using something like Tuple.Create(), so you get that info with each update:
{A - 1}, {B - 101} etc. Your where can then do:
where selector ? merged.Item1 == A : merged.Item1 == B //this maps 'true' to feed A
I also used a Switch, which will cause my sample streams to restart because they are not published.
You probably want to publish yours and Connect them (make them 'hot'), so a Switch like mine doesn't cause any new side effects in the subscription. You have a subject (which is hot), but the 'behaviour' part will replace the value you passed into the constructor. Publishing and connecting would prevent that.
Shout if you are still confused. This isn't a full answer, but might give you enough to think about.
Howard.
Now much closer to your original question:
void Main()
{
var valueStreamA = new BehaviorSubject<int>(0);
var valueStreamB = new BehaviorSubject<int>(100);
var selectorStreamA = valueStreamA.Select(id => Tuple.Create("A", id)).Publish();
var selectorStreamB = valueStreamB.Select(id => Tuple.Create("B", id)).Publish();
var selectorStream = new BehaviorSubject<bool>(true);
var query = from selector in selectorStream
select from merged in selectorStreamA.Merge(selectorStreamB)
where selector == true ? merged.Item1 == "A" : merged.Item1 == "B"
select merged.Item2;
query.Switch().Subscribe(Console.WriteLine);
selectorStreamA.Connect();
selectorStreamB.Connect();
//First we get 0 output (because we are already using stream A, and it has a first value)
valueStreamA.OnNext(1); //This is output, because our selector remains as 'A'
valueStreamB.OnNext(101); //This is ignored - because we don't take from B
selectorStream.OnNext(false); //Switch to B
valueStreamA.OnNext(2); //Ignored - we are now using B only
valueStreamB.OnNext(102); //This is output
selectorStream.OnNext(true); //Switch back to A.
}
Outputs:
0
1
102
is there a way to return an object from a comprehension in coffeescript? something so that i could express this:
form_values = () ->
ret = {}
ret[f.name] = f.value for f in $('input, textarea, select')
return ret
like this:
form_values = () -> f.name, f.value for f in $('input, textarea, select')
i'd like to construct a single object (not an array of objects). so if the markup looks something like this:
<form name=blah>
<input type=text name=blah1 value=111 />
<textarea name=blah2>222</textarea>
<select name=blah3>
<option value=333a>
<option value=333b>
</select>
</form>
the returned object would be something like this:
{
blah1: '111',
blah2: '222',
blah3: ''
}
form_values = new ->
#[f.name] = f.value for f in $ 'input, textarea, select'
this
or
form_values = new class then constructor: ->
#[f.name] = f.value for f in $ 'input, textarea, select'
Nope. Comprehensions only return arrays in CoffeeScript. Search the issue tracker for object comprehensions, and you'll find several proposals, but none were found suitable.
Check the functional library underscore and the extension _.mash from this mixin:
form_values = ->
_($('input, textarea, select')).mash f -> [f.name, f.value]
Using underscore's object function, you can do this:
form_values = _.object([f.name, f.value] for f in $('input, textarea, select'))
This has already been answered but probably lack of some explanations as this idiom is rather cryptic at first sight:
form_values = (new -> #[f.name] = f.value for f in $ 'input, textarea, select'; #)
// ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^
// create with |
// a new that |
// empty anonymous |
// object constructor |
// don't forget -/
// to return the
// newly created object
The key idea is to create an empty object (new) with an anonymous constructor (-> ...) that will create the various fields.
CoffeeScript's creator suggests using a helper function to convert an array of pairs into an object:
form_values = toObject([f.name, f.value] for f in $('input, textarea, select'))
This is arguably the most readable way of doing it, within the current language syntax. It's also very similar to how Python and other languages do it, except for the missing syntactic sugar.
The helper function can be easily written once, using for example the technique from #matyr's and #Sylvain's answers:
// Create a new object from an array of [key, value] pairs.
toObject = (pairs) ->
new -> #[key] = value for [key, value] in pairs; #
I believe you can do this with no added libraries right in CoffeeScript.
It should be something to the effect of:
$('input, textarea, select').each (item) => #form_values || #form_values = {}; #form_values[$(item).name] = $(item).value
You could simplify the syntax of that by pre-creating the form_values:
form_values = {}
$('input, textarea, select').each (item) -> form_values[$(item).name] = $(item).value
Here is a lengthier response with canned examples:
Take a very simple example where you wanted to map the obj to name value:
items = [ { a: 1 }, { b: 2 }, { c: 3 } ]
items.map((item) -> {name: Object.keys(item)[0], value: item[Object.keys(item)[0]]})
[ { name: 'a', value: 1 },
{ name: 'b', value: 2 },
{ name: 'c', value: 3 } ]
Note that the above is not really an Object comprehension, just demonstrating an example.
Now let's say there is a bit more structure and you just want to map a known unique key:
items = [{key: "abc", someVar: 1}, {key: "def", someVar: 2}]
In Python you'd do something simple like this: {x['key']:x for x in items}
In CoffeeScript you can get all of this down to one single line though with a caveat:
items.forEach (item) => #x || #x = {}; #x[item['key']] = item
{ abc: { key: 'abc', someVar: 1 },
def: { key: 'def', someVar: 2 } }
In the above code x was not previously defined in the scope, so using => and # allowed us to bind x with the #x || #x = {} if not previously found, then set the key.
If you don't want to use => and # you have to define x beforehand:
x = {}
items.forEach (item) => x || x = {}; x[item['key']] = item
{ abc: { key: 'abc', someVar: 1 },
def: { key: 'def', someVar: 2 } }
Not to beat a dead horse, but I personally thing this is readable and satisfies the 'one line' requirement without needing extra modules:
form_values = {}; form_values[f.name] = f.value for f in $('input, textarea, select')
Don't forget you can still use a semi-colon to combine lines in Coffeescript!