00:06 In the previous episode of this series we built a reactive list. Today we'll use this component to build a reactive, observable array that we can eventually feed to a table view. We're going to need operations like filtering and sorting, and changes to the original array should be funnelled to the filtered and sorted array as well.
01:05 We remove the sample code from last time and start writing our reactive array. It's based on an initial value and a list of changes. The signature of the change list looks impressive with all those generic brackets, but simply said, it's a property — so that it can be observed — holding a list of array changes:
02:41 In the reactive array, we want to calculate the current value by applying the array changes to the initial array. In an extension on Array, we write the apply method. With this mutating method we can also provide a non-mutating version, which copies the array:
05:11 Now we calculate the latest value of an RArray by applying all changes to its initial value. We should be able to observe this latest value, so we wrap it in a Property. To apply the changes, we call the reduce method we wrote in the previous episode:
09:41 At this point, we can observe the latest value of an array, append changes, and get notified with the value that results from applying all changes to the initial array. That's a lot of overhead to create a mutable array, but the cool thing is that we can now build reactive methods on top of it so that we can filter and sort the array and observe the latest result of these operations. Before we add filtering, we can do some refactoring.
10:36 We move the sample code into a convenience method that constructs a mutable RArray from an initial value alone and returns it along with a function to append changes:
13:49 The purpose of the filter method is to create a filtered RArray. If the original array changes in a way that affects the filtered array, then these changes should be applied there as well, and we want to get notified.
14:09 We take the initial value, filter it, and return a mutable RArray without exposing the addChange function:
16:19 Now we want to change arr and see this change reflected in the filtered array. In the filter method, we have to observe the original array's changes property. When the list of changes is updated, we receive the latest changes as an RList that can be used to reduce:
17:19 The changes use indices that refer to the initial array, so we have to start reduce with the initial array value as well and work our way through the changes. In the combine function, we get the intermediate version of the array and the current change to apply. In addition to applying the change, we switch over it to see how we process both cases for the filtered array:
19:43 An insertion into the original array can be ignored if the value shouldn't be included in the filtered array. Likewise, a removal from the original array can be ignored if the value wasn't included in the filtered array. We can add these conditions to our switch statement. We also have to add a default case in which we don't do anything:
25:18 The value 4 got inserted, but the filtered array has the wrong value. It should contain 2 and 4, but it still only contains 2. Apparently, the change doesn't get included in the RArray we got from the filter method.
25:59 If we create the filtered array before changing the original array, we do get the expected result:
26:18 It turns out that the filtered array starts observing the changes from the moment we create it, but it doesn't take into account the initial list of changes. We fix this bug by performing the filter's reduce operation straight away, with the current value of the changes list:
28:58 It's not easy to write these reactive algorithms. On the plus side, we don't have to keep writing them — once we have filter and sort for a reactive array and we've tested them well, we can keep using and combining them. We could also port these operations to a ReactiveSequence or ReactiveCollection protocol and make them work for all kinds of reactive structures at once.
29:47 We're almost ready to let our reactive components drive a table view; we only need a way to sort elements in a custom order. Once we add sorting, we can compose the reduce, filter, and sort operations and observe changes of the result. In the observer, we'll have access to the correct indices, which we can directly apply to a table view. Let's do all that next time!