I am currently trying to understand a problem with recursion. This code checks to see if a node is a leaf node, if it is it will increment the amount of leaf nodes.
I can't understand what the fn.call(this) does and then how it then calls the closure inside the for loop.
Here is my code.
class TreeNode {
String name
List<TreeNode> children = []
// if no children, there is no leaf node
boolean isLeaf() {
return !children
}
void walkTree(Closure fn) {
fn.call(this)
for (child in children) {
child.walkTree(fn)
}
}
}
testTreeNode = new TreeNode(name: "Fred", children: [
new TreeNode(name: "Janet", children: [
new TreeNode(name: "Mark"),
new TreeNode(name: "Anne", children: [new TreeNode(name: "Simon") ]),
new TreeNode(name: "Kelly")
]),
new TreeNode(name: "Nigel")
])
def leafCount = 0
testTreeNode.walkTree { node -> if (node.leaf) leafCount++}
I hope I'm following correctly, but it seems you have 2 questions:
1. What does fn.call(this) do?
Firstly, a Closure is an anonymous block of code that can be executed at a later time.
When you call testTreeNode.walkTree, you are passing the Closure (block of anonymous code) node -> if (node.leaf) leafCount++ as a parameter of the walkTree method, so that closure becomes the variable named fn within the context of walkTree.
Within the walkTree method, the Closure (block of code) is then being explicitly invoked using the Closure.call(args) method.
See: http://groovy-lang.org/closures.html#_calling_a_closure
2. How is the closure executed inside the for loop?
As the closure can be referred to using the fn variable name, you are then able to pass that as an argument directly to walkTree for each child TreeNode in the loop, which then invokes that closure using fn.call(this).
If we substitute the Closure usage with the block of code passed, it might be clearer what is happening:
void walkTree(Closure fn) {
//Closure executed here
if (this.leaf) leafCount++
for (child in children) {
//closure passed as argument to walkTree method of child TreeNodes
child.walkTree { node -> if (node.leaf) leafCount++ }
}
}
Related
I am trying to create an array which contains my struct Element. Trying to use .append I get two errors.
"Cannot use mutating member on immutable value: 'self' is immutable" and "Cannot convert value of type 'Element' to expected argument type '[Element]'"
I'm obviously doing this all wrong.
My test code:
var elements = [[Element]]()
var body: some View {
VStack {
ForEach (0..<26) { index in
Text("\(index) Hello, World!")
elements.append(Element(direction: "Direction \(index)", movement: "Movement \(index)", multiplier: index))
}
}
}
}
struct Element {
var direction: String
var movement: String
var multiplier: Int
}
You cannot perform any operation inside the ForEach. The ForEach expects to have a single View returned from it. But if you want to append data inside the ForEach then you can do that when the onAppear() closure is called on your View which is inside the ForEach.
This is what your code will look like when the elements array is appended in the onAppear of your View.
VStack {
ForEach (0..<26) { index in
Text("\(index) Hello, World!").onAppear() {
elements.append(Element(direction: "Direction \(index)", movement: "Movement \(index)", multiplier: index))
}
}
}
And you are getting the "immutable error" because you're probably declaring your elements variable inside the struct and properties inside the struct are immutable. So to be able to append new values you either need to annotate your elements variable with #State or you can declare it outside of the struct
Outside of struct declaration:
var elements: [Element] = []
struct MyView: View {
}
With annotation but inside struct declaration:
struct MyView: View {
#State var elements: [Element] = []
}
And you also need to know that changing values of #State annotated properties updates the UI but this shouldn't be something to worry about as SwiftUI calculates the changes in the UI and updates only the new changes
Sorry if that title is not clear enough but I didn't know how to sum it up in one sentence.
I have a webservice that returns an ArrayList of objects named Father.
The Father object is structured like this:
class Father {
ArrayList<Child> children;
}
I have another webservice that returns me the detail of the object Child.
How can I concat the first call that returns me the arraylist of Father and the multiple calls for the multiple objects Child ?
So far I can make the calls separately, like this:
Call for ArrayList of Father
myRepository.getFathers().subscribeOn(Schedulers.io())
.observeOn(Schedulers.io()).subscribeWith(new DisposableSingleObserver<List<Father>>() {
})
multiple call for ArrayList of Child
childListObservable
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.flatMap((Function<List<Child>, ObservableSource<Child>>) Observable::fromIterable)
.flatMap((Function<Child, ObservableSource<Child>>) this::getChildDetailObservable)
.subscribeWith(new DisposableObserver<Child>() {
// do whatever action after the result of each Child
}))
Prerequisite
Gradle
implementation("io.reactivex.rxjava2:rxjava:2.2.10")
testImplementation("io.mockk:mockk:1.10.0")
testImplementation("org.assertj:assertj-core:3.11.1")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.3.1")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.3.1")
Classes / Interfaces
interface Api {
fun getFather(): Single<List<Father>>
fun childDetailInfo(child: Child): Single<ChildDetailInfo>
}
interface Store {
fun store(father: Father): Completable
fun store(child: ChildDetailInfo): Completable
}
class ApiImpl : Api {
override fun getFather(): Single<List<Father>> {
val child = Child("1")
val child1 = Child("2")
return Single.just(listOf(Father(listOf(child, child1)), Father(listOf(child))))
}
override fun childDetailInfo(child: Child): Single<ChildDetailInfo> {
return Single.just(ChildDetailInfo(child.name))
}
}
data class Father(val childes: List<Child>)
data class Child(val name: String)
data class ChildDetailInfo(val name: String)
Solution
val fathersStore = api.getFather()
.flatMapObservable {
Observable.fromIterable(it)
}.flatMapCompletable {
val detailInfos = it.childes.map { child ->
api.childDetailInfo(child)
.flatMapCompletable { detail -> store.store(detail) }
}
store.store(it)
.andThen(Completable.concat(detailInfos))
}
On each emit of a List of fathers, the list is flatten. The next opreator (flatMapCompletable) will take an Father. The completable will get the details of each Child with Api#childDetailInfo. The result is build by calling the API one by one. There is no concurrency happening wegen "concat". When the father is stored sucessfully, the childs will be stored as-well, when retrieved successfully. If one of the API-calls fails (e.g. network) everything fails, because the onError will be propgated to the subscriber.
Test
#Test
fun so62299778() {
val api = ApiImpl()
val store = mockk<Store>()
every { store.store(any<Father>()) } returns Completable.complete()
every { store.store(any<ChildDetailInfo>()) } returns Completable.complete()
val fathersStore = api.getFather()
.flatMapObservable {
Observable.fromIterable(it)
}.flatMapCompletable {
val detailInfos = it.childes.map { child ->
api.childDetailInfo(child)
.flatMapCompletable { detail -> store.store(detail) }
}
store.store(it)
.andThen(Completable.concat(detailInfos))
}
fathersStore.test()
.assertComplete()
verify { store.store(eq(Father(listOf(Child("1"), Child("2"))))) }
verify { store.store(eq(Father(listOf(Child("1"))))) }
verify(atLeast = 2) { store.store(eq(ChildDetailInfo("1"))) }
verify(atLeast = 1) { store.store(eq(ChildDetailInfo("2"))) }
}
Please provide next time some classes/ interfaces. When your question contains all vital information, you will get an answer quicker.
I'm attempting to use a struct to manage accessing nodes on a tree. Whenever I access the method of the parent's child node, the parent reference on the subsequent call gets lost (i.e. parent.child.method(child) -> [parent becomes nil]-> parent(the previous child).child ... etc).
Here is the error snippet from my file.
type Node struct {
Left *Node
Right *Node
value int
}
func (parent *Node) determineSide(child *Node) (Node, Node) {
if child.Value < parent.Value {
if parent.hasLeftNode() {
return parent.Left.determineSide(child)
}
return parent.addLeftNode(child)
} else if child.Value > parent.Value {
if parent.hasRightNode() {
return parent.Right.determineSide(child)
}
return parent.addRightNode(child)
}
return *child, *parent
}
I attempted to solve this by trying to find a way to inform the method that the new reference should be parent.Left. Things like using *parent.Left and &parent.Left didn't seem to be correct.
A solution may might be to move this code outside of the struct and have another function handle the outcome for a quick fix, but I'd like to understand why this isn't working out of the box. Thought process here is influenced by using this.child.determineSide(child).
Full code is here.
Edit
Here is some output from the terminal that might give even further context. Looks like I'm having a check type issue leading to the problem.
parent &{<nil> <nil> 2}
parent.Left <nil>
parent.LeftNode true
child &{<nil> <nil> 1}
parent <nil>
child &{<nil> <nil> 1}
Okay, I know what u'r exactly asking finally.
New() methods returns a value, not a pointer, which means u can't see later change in caller. What the caller got is only a value copy of the Node. So the parent what u print will always be {Left:<nil> Right:<nil> Value:2}.
So the same with addLeftNode() and addRightNode().
Just use pointer, not value to achieve your goal.
See pointers_vs_values
I think it's just the Visit() method where the problem is.
It will never visit right child when u immediately return after visited left child.
The left and right child are not mutually exclusive, so the second if-clause should not use else if, which would be if.
The visiting order also has problem.
Before:
// Visit will automatically walk through the Child Nodes of the accessed Parent Node.
func (parent *Node) Visit() (Node, int) {
fmt.Println("Node value:", parent.Value)
if parent.hasLeftNode() {
return parent.Left.Visit()
} else if parent.hasRightNode() {
return parent.Right.Visit()
}
return *parent, parent.Value
}
Modified:
// Visit will automatically walk through the Child Nodes of the accessed Parent Node.
func (parent *Node) Visit() (Node, int) {
if parent.hasLeftNode() {
parent.Left.Visit()
}
fmt.Println("Node value:", parent.Value)
if parent.hasRightNode() {
parent.Right.Visit()
}
return *parent, parent.Value
}
Additionally, as to me, Visit() shouldn't return any values.
Problem originated from incorrect type checking. The function successfully handled the call, but the method I was using wasn't accurate in confirming whether a node was assigned.
// isNode checks whether the provided property is a Node.
func (parent *Node) isNode(property interface{}, typeset interface{}) bool {
fmt.Println(reflect.TypeOf(property) == reflect.TypeOf(typeset))
// this always referred to the address for the base Node struct or similar falsy.
return reflect.TypeOf(property) == reflect.TypeOf(typeset)
}
// hasLeftSide tests whether the Parent Node has a Node assigned to its left side.
func (parent *Node) hasLeftNode() bool {
return parent.Left != nil //parent.isNode(parent.Left, (*Node)(nil))
}
// hasRightSide tests whether the Parent Node has a Node assigned to its right side.
func (parent *Node) hasRightNode() bool {
return parent.Right != nil // parent.isNode(parent.Right, (*Node)(nil))
}
I'm dealing with some asynchronous functions and trying to update views. In short I have function 1 with asynchronous function that will return a string to be passed to function 2. I am updating views in both functions, on main thread. It all works but I need to understand if this is correct way.
class A {
var varA = ""
var varB = ""
func f1 (_ completion: #escaping (String) -> void ){
some asynchronous call ... { in
...
DispatchQueue.main.async {
self.varA = "something"
sef.labelA.text = self.varA
completion(self.varA)
}
}
}
func f2 (_ string: String){
another asynchronous call ... { in
...
DispatchQueue.main.async {
self.varB = string
sef.labelB.text = self.varB
}
}
}
// funcation call
f1(completion: f2)
}
Three questions, 1) What is the right way to run a dependent function where there is wait for an asynchronous callback?
2) Is DispatchQueue.main.async needed to update views?
3) Is it ok to call async func in another async callback? Isn't there chance self may be nil in some cases if you are updating views in some escaping function?
I'm going to try helping you according to your questions:
Question 1) There are many right ways and each developer can have its own logic, but in this case, what I personally would probably do is something like this:
class A {
func f1 (_ completion: #escaping (String) -> void ){
some asynchronous call ... { in
...
DispatchQueue.main.async { [weak self] in // 1
guard let strongSelf = self else { return } // 2
let varA = "something" // 3
strongSelf.label.text = varA
completion(varA) // 4
}
}
}
func f2 (_ string: String){
another asynchronous call ... { in
...
DispatchQueue.main.async {
sef.labelB.text = string // 5
}
}
}
// function call
// 6
f1(completion: { [weak self] text in
guard let strongSelf = self else { return }
strongSelf.f2(text)
})
}
1 - Here I'm using [weak self] to avoid retain cycles.
2 - Just unwrapping the optional self, case it's nil, I'll just return.
3 - In your case, it's not really necessary to have class variables, so I'm just creating local variables inside the block.
4 - Finally, I'm calling the completion with the variable containing the string.
5 - I also don't really need to set a class variable in here, so I'm just updating the label text with the string provided as a paramater.
6 - Then, I just need to call the first function and use the completion block to call the second after the first one completes.
Question 2) Yes, you must call DispatchQueue.main to update the view. This way your making sure that your code will be executed in the main thread that is crucial for things interacting with UI because it allow us to have a sincronization point as you can read in Apple's documentation.
Question 3) Using [weak self] and guard let strongSelf = self else { return }, I'm avoiding retain cycles and the cases where self can be nil.
At work, we are discussing about a simple (or not so simple) question. ¿Is there any difference between the following invocation methods?
class Obj {
def num
def prtn = {
print this.num
}
}
def listObj = [new Obj(num:1), new Obj(num:2), new Obj(num:3), new Obj(num:4)]
// End Common code
// Method #1
def lst = listObj.collect{ obj-> obj.prtn() }
// Method #2
def lst = listObj.collect{ obj-> { -> obj.prtn()} }.each{ it() }
// Common code
The side-effect of both statements is the same: they print "1234". But the return value is different.
The prtn method always returns null, so the value of listObj.collect{ obj-> obj.prtn() } is [null, null, null, null].
In the case of listObj.collect{ obj-> { -> obj.prtn()} }.each{ it() }, as each returns the collection on which it was invoked, the result will be a list of Closure objects (as that is what listObj.collect{ obj-> { -> obj.prtn()} } returns).
In general, if you only want to iterate a collection for some side effect, use each; if you want to transform it into a different collection, use collect. And try no to mix both side-effect iteration and transformation :)
You can also do:
listObj*.prtn()
And this gives the same result as your Method #1