New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to change Vec sorting based on a signal #13
Comments
Yup, that's exactly what |
Hmm.. The closure passed to let list = signal_vec::always(vec![3, 1, 6, 2]).map(Rc::new);
#[derive(Copy, Clone)]
enum FilterOption { Odd, Even }
let filter_option = Rc::new(Mutable::new(FilterOption::Odd));
let mut signal = list
.filter_signal_cloned(|item| {
let item = Rc::clone(item);
let filter_option = Rc::clone(&filter_option);
filter_option.signal_ref(move |filter_option| {
match filter_option {
FilterOption::Odd => *item % 2 != 0,
FilterOption::Even => *item % 2 == 0,
}
})
}); But the closure passed to let list = signal_vec::always(vec![3, 1, 6, 2]).map(Rc::new);
#[derive(Copy, Clone)]
enum SortOption { Incr, Decr }
let sort_option = Rc::new(Mutable::new(SortOption::Incr));
let mut signal = list
.sort_by_cloned({
let sort_option = Rc::clone(&sort_option);
move |left, right| {
match sort_option.get() {
SortOption::Incr => left.cmp(&right),
SortOption::Decr => right.cmp(&left),
}
}
}); Or maybe I'm missing something? |
@njam Normally I'd recommend using Let me think about the best way to fix this. P.S. You don't need to wrap |
So, after thinking about it, I think implementing |
Just a thought. |
Yeah, I think it will need to be something like that, because having |
I recently implemented a let signal = map_mut! {
let list = list.to_signal_cloned(),
let sort_option = sort_option.signal() => {
list.sort_by(|left, right| {
match *sort_option {
SortOption::Incr => left.cmp(&right),
SortOption::Decr => right.cmp(&left),
}
});
list
}
}; This will resort the entire list whenever it changes, which isn't optimal for performance, but at least it works. |
Got it thanks! Should I close this ticket then? For reference, here's a full example with this functionality: |
I'd still like to have a more efficient method specialized to this use case, but it's tricky to do it right. |
I guess the most efficient implementation would apply granular As an approximation for such behaviour I am now just replacing my |
@njam Yes, that part is easy, the tricky part is the public API. If you use |
But if I use |
Yes, that's correct. That's the problem that the more efficient method is supposed to solve. So in the meantime replacing the |
After thinking about it some more, I figured out a really good API. I just published version sort_option.signal().switch_signal_vec(move |sort_option| {
mutable_vec.to_signal_vec().sort_by_cloned(move |left, right| {
match sort_option {
SortOption::Incr => left.cmp(&right),
SortOption::Decr => right.cmp(&left),
}
})
}) The way that it works is:
So the end result is that you will get incremental changes for the What I really like about this design is that it isn't specific to sorting: you can use For example, you might be doing some URL routing, and you want to change the webpage based on the URL. So you could use url.signal().switch_signal_vec(move |url| {
match url {
"/foo" => return_signal_vec_for_foo(),
"/bar" => return_signal_vec_for_bar(),
}
}); |
Nice, works great, thanks! |
Let's say I have a
Vec
of things, and I'd like to sort it on-the-fly based on a sort-option (by size, by name, etc..). Whenever the sort-option changes, the vector items should be updated accordingly.Is it possible to sort a SignalVec based on a closure that gets re-evaluated when a signal triggers? I can see for filtering there is
filter_signal_cloned()
, but I can't see something similar for sorting. Is it even feasible?The text was updated successfully, but these errors were encountered: