Comments (3)
Hi @xperiandri.
You are right. 👍 We need a way to patch items like react does with its vdom.
One way to do this is to use patch algorithm like the Levenstein distance (https://en.wikipedia.org/wiki/Levenshtein_distance). It has a O(m*n) complexity so it could have performance issue on large collection. I wrote a small extension method on ObservableCollection without much tests so it could contains bugs:
public static class ObservableCollectionExtensions
{
public static void LevenshteinPatch<T>(this ObservableCollection<T> source, IList<T> target)
{
if(source.Count == 0 && target.Count != 0)
{
foreach(var item in target)
{
source.Add(item);
}
return;
}
if(target.Count == 0)
{
source.Clear();
return;
}
var matrix = BuildLevenshteinMatrix(source, target);
ApplyLevenshteinMatrix(source, target, matrix);
}
private static int[,] BuildLevenshteinMatrix<T>(ObservableCollection<T> source, IList<T> target)
{
var m = new int[source.Count + 1, target.Count + 1];
for (var i = 1; i < source.Count; i++)
{
m[i, 0] = i;
}
for (var j = 1; j < target.Count; j++)
{
m[0, j] = j;
}
for (var j = 1; j < target.Count + 1; j++)
{
for (var i = 1; i < source.Count + 1; i++)
{
var substitutionCost = Equals(source[i - 1], target[j - 1]) ? 0 : 1;
var deletion = m[i - 1, j] + 1;
var insertion = m[i, j - 1] + 1;
var substitution = m[i - 1, j - 1] + substitutionCost;
m[i, j] = Min(deletion, insertion, substitution);
}
}
return m;
}
private static void ApplyLevenshteinMatrix<T>(ObservableCollection<T> source, IList<T> target, int[,] matrix)
{
var i = source.Count;
var j = target.Count;
while (i > 0 && j > 0)
{
if (matrix[i - 1, j] < matrix[i, j])
{
i--;
source.RemoveAt(i);
}
else if (matrix[i, j - 1] < matrix[i, j])
{
j--;
source.Insert(i, target[j]);
}
else if (matrix[i - 1, j - 1] < matrix[i, j])
{
i--;
j--;
source[i] = target[j];
}
else
{
i--;
j--;
}
}
for (var k = 0; k < j; k++)
{
source.Insert(k, target[k]);
}
for (var k = 0; k < i; k++)
{
source.RemoveAt(0);
}
}
private static int Min(int a, int b, int c)
{
var min = a < b ? a : b;
return min < c ? min : c;
}
}
A more efficient way to do it would be to extract a unique key for each item to reduce the complexity. React documentation explain it briefly : https://facebook.github.io/react/docs/reconciliation.html
If you are interested in this, Inferno has a great algorithm to patch keyed children :
https://github.com/infernojs/inferno/blob/master/packages/inferno/src/DOM/patching.ts#L462
I would be great if Redux shipped a custom INotifyCollectionChanged collection or an extension method on ObservableCollection to patch items.
If someone is interested to make a PR, I would be glad to review it and merge it!
from redux.net.
Extension method will not be as efficient as custom collection, a collection can batch update as a batch update within args of a single time raised event. Maybe not single time but not as much as 4 times. I don't remember the args type implementation
from redux.net.
I don't really know what the issue is here, but it seems the core of it is that something akin to a ListView is fully re-rendered even though only part of a collection in the state has changed, because the state collection does not implement INotifyCollectionChanged (and, indeed, is not and should not be mutable).
What about having a view model where you bind the control to to a local ObservableCollection that you update from the immutable collection in the state?
Sorry if I totally missed the point here.
from redux.net.
Related Issues (20)
- Make compatible with .NET Standard HOT 4
- Saga HOT 23
- Is the return value from Store.Dispatch useful for anything? HOT 13
- What is the point of this Redux.NET line HOT 3
- [Question] Any plans for state persistence? HOT 1
- Future of Redux.NET / version 3.0 HOT 29
- Create store bug HOT 9
- Refactor GetState() to State (property) HOT 2
- Make InnerDispatch protected virtual
- New ActionDispatched event would duplicate StateChanged HOT 11
- Won't compile in Xamarin HOT 2
- Question about Dispatching Actions. HOT 3
- What's the status of this project? HOT 19
- WPF Dev Tools don't work
- C#.NET Windows Applications. HOT 8
- Is this Dead project & no longer being maintenance? HOT 2
- Could not link assemblies HOT 1
- The call is ambiguous between the following methods or properties: 'System.ObservableExtensions.Subscribe<T>(System.IObservable<T>, System.Action<T>)' and 'System.ObservableExtensions.Subscribe<T>(System.IObservable<T>, System.Action<T>)' HOT 1
- Nuget Package should be marked deprecated.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from redux.net.