Wow, I can't believe that on the top-right corner, the picture is taken in my hometown Yilan!!! Oh get back to this clip, great video. I happen to search for "flatten nested arrays" and your video showed up. Glad I came in to watch this vid.
You're awesome Brian, I love how you put emphasis on algorithms and logical thinking and not just on pure code production. As you said, most often we just c/p solutions from stackoverflow and adjust it here and there.
You are legitly the best code teacher on youtube. Love the explanation of logic that you go through. Definitely makes a difference when trying to learn.
I love these types of exercises. Most people that cannot solve these exercises usually cannot make it past interviews. These are just some of the problems we solve as software engineers, so for people that don't enjoy it, it'll be hard to enjoy programming.
Superb brian.. i have an doubt at which sinario will use this type of algarith And can u make an video on expandable collectionview Initially all cell are in collapsed state... i mean we need to show only sections intially... After clicking any one of the section should expand items corresponding section.... If i click another section previous section should be closed. And selected section should expand Thank you brian
Thanks, it's really difficult to tackle these challenges if you start from a very difficult use case. Similar to whiteboarding exercises, you should always begin with the most basic example of your inputs.
Hey Brian.. Pretty good stuff. I was able to before it out before watching the video although it took me an hour to do so. One thing I would suggest is in else if element is [Any], we don't need that as we already know if element is not Int it will be Any only. So its kind of ambiguous calling. Also, inside else if we are again saying element is Any. So, writing else only will work perfectly! Thank you for this video. Need more like this please.
Hey Eduardo, every course is done programmatically, this way students understand exactly whats going on. Videos 1-40 are recorded in Swift 3, 41-47 are in Swift 4. Each lesson comes with source code that you can compile in Swift 3 and Swift 4, so don't worry if anything goes wrong, which is pretty rare since Swift 4 syntax changes are minor.
Hi I know it has been a while but I just found this video. Instead of creating an extra variable of recursionResult and that for loop, I just wrote "myFlatenedArray += flatenArray(element as! [Any])". It seems simpler, but I am wondering, is there a difference between appending an array to another with for loop vs using the + to merge two arrays? Would there be a time difference, or are they actually the same?
Hi Brian, Can you please help? I don't understand one thing: when the recursion calls, flattenArray(nestedArray: element as! [Any]), will " var myFlattenedArray = [Int]() " be called every time? Like the example with [1, [2]], when flattenArray(nestArray: [2]) calls, if " var myFlattenedArray = [Int]() " is called, then myFlattenedArray will be empty. Thanks a lot! Mike
Hey, it is great, can you tell me the complexity of your algorithm? and also it would be really helpful if you could talk and give some examples of using "FlattenBidirectionalCollection"
func testy(holder: Array) -> Array { for x in holder { if x is [Any] { testy(holder: x as! Array) } else { holdy.append(x) } } return holdy } This is what I came up with, but it seems a little different. I didn't set the recalled function to anything; I just called it. Also, I never checked for the type, I simply made sure it would handle anything that wasn't itself an array of any type. Would this approach present any issues?
Hello Sir I am Shailesh My question is How we get update if any contact is added in iPhone than update that contact number to the server how develop that code in swift 3
Awesome as always, learn so much by trying to do it first then following to see how you did it differently, one quick question, why do you say 'bang' for '!' ? Also is it quicker to add the arrays together instead of doing another for loop to append: myFlattenedArray += flattenArray(nestedArray: element as! [Any]) Thanks!
! is often called 'bang' in software development. I originally used += on the recursive result but I thought it would be confusing to show this new bit of code.
I think this could be even neater with an extension of Array; extension Array { func flatten() -> [Any] { var result = [Any]() for obj in self { if let cast = obj as? [Any] { result.append(contentsOf: cast.flatten()) } else { result.append(obj) } } return result } } let arr: [Any] = [0, 1, [2, [3, 4]]] let arr2: [Any] = [0, 1, 2, 3, [4]] print(arr.flatten()) print(arr2.flatten())
Dr1zak haha. You just new in programming. Never create thing that already exist. Never recreate a bicycle. Always use libraries. Always use that already exist. Even Uber, Instagram use same libraries as we. For example dagger 2, retrofit, rxjava, retrofit. Everyone use libraries. Even big companies as Uber. Hope I gave you some path for growing in world of programming
In python3, it can be done like below: List = [ ] def flatten(x): for i in x: if isinstance(i,int): List.append(i) elif isinstance(i,list): flatten(i) return List print(flatten(x))
Wow! Awesome I've done almost the same code! def flatter(input_list,x=[]): for item in input_list: if not isinstance(item, list): x.extend([item]) else: flatter(item,x) return x
Brian I need your help! I have a great idea for an app, but I'm torn on what platform to make it on (android or iOS). I have never developed for either of them so I am a very huge noob! I looked at android studio but I got very intimidated by the look and feel of android studio, but i can't say Xcode feels more comfortable because never used it. And also to mention, I have barely any experience in java but I have a great understanding of c++. Also I have a windows computer so if I should develop for iOS I would either have to buy a Mac or make my co punter a hackintosh. So in my situation, what would you recommend I do?
Android is the easiest route. Transitioning to Java from C++ is probably easier instead of C++ => Swift. And then you have the hackintosh issues and it should be a no-brainer by now...
+Lets Build That App nice video and solution! What do you think of the following approach: func flatten(_ arr: [Any]) -> [Int] { guard !arr.isEmpty else { return [] } let queue = arr.count > 1 ? Array(arr[1...arr.count-1]) : [] if let num = arr.first as? Int { return [num] + flatten(queue) } return flatten(arr.first as? [Any] ?? []) + flatten(queue) }
I guess in that case you can avoid another "for loop", you write less code, it is easier to read and maintain + I think it might work faster, than looping through each element and appending it. It seems to be not important at all, but when we deal with really large arrays with tons of elements, then every half of a second might count. Just thinking ^_^
append(contentsOf: Sequence) appends all the elements of a sequence. It just reduces the number of lines of code and Apple might have some tricks to making it more efficient.
I think this algorithm will be more flexible if we will use generic type instead of Int type. It will be great if Brian will update this lesson with Generic implementation )
let my = [[[["binay"]]],[45],454,3,["dell",["car","sun"]]] as Array func myFlatArryWithVal( _ myArrVal: [Any]) -> [Any] { var myArr = [Any]() for elements in myArrVal{ if (elements is Array){ let res = myFlatArryWithVal(elements as! [Any] ) for res2 in res{ myArr.append(res2) } }else{ myArr.append(elements ) } } return myArr } print(myFlatArryWithVal(my)) output ["binay", 45, 454, 3, "dell", "car", "sun"]
Hey Brian! I'm a college student currently taking games development in which I learn some programming languages ( C# and GML ) and also learn aspects of design such as 3D modelling and UI. I wish to proceed into university to get a masters degree in software or mobile app engineering. Is it worth it? Will my salary be much greater and will it be better off in the long run to proceed to achieve my masters at the expense of around about $45,000 of student loans for that extra degree? :D Thanks. Hope you reply!
Hi. How is it possible that's you can call in function flattenArray, inside itself (the recursion part at line 15) and use element as! [Any] as the argument for func flattenArray? That's like trying to eating a bread before you even got to buy the bread. Thanks. God bless, Proverbs 31
he's basically passing the current index of the array, and the index is an array so he's casting as an array of type any and then performing the same process on that index of type array; basically check if the values are of type int and then appending to the result. If at any point there aren't any objects of type array then it doesn't satisfy the condition on line 13 and just simply returns the result.
That was my attempt def flatter(input_list,x=[]): for item in input_list: if not isinstance(item, list): x.extend([item]) else: flatter(item,x) return x
here is another solution that I thought was a little more elegant: func flattenArray(array: [Any]) -> [Any] { var final:[Int] = [] array.forEach { i in if let arr = i as? [Any] { final.append(contentsOf: flattenArray(array: arr) as! [Int]) } else { final.append(i as! Int) } } return final } you could also make this an extension to array so that it works for all types of arrays
Hey brain, greetings from China. My solution with generics: extension Array { static func flatten(_ array: [Any], elementType: E.Type) -> [E] { var result = [E]() for item in array { switch item { case let nestedArray as [Any]: result.append(contentsOf: flatten(nestedArray, elementType: elementType)) case let individual as E: result.append(individual) default: assert(false, "Element type does not match.") } } return result } } extension Array where Element == Any { func flattened(elementType: E.Type) -> [E] { return Array.flatten(self, elementType: elementType) } } Usage: let intArray = [1, [2, [3, [4, [5, 6, 7]]]]] as [Any] intArray.flattened(elementType: Int.self) // [1, 2, 3, 4, 5, 6, 7] let stringArray = ["a", "b", ["c", [], [["d"]]]] as [Any] stringArray.flattened(elementType: String.self) // ["a", "b", "c", "d"] let mixedArray = ["你好", "谢谢", 123, [4, "再见", [], [[567, ""]]]] as [Any] mixedArray.flattened(elementType: Any.self) // ["你好", "谢谢", 123, 4, "再见", 567, ""] Some tips here: 1. Use switch statement for type casting 2. Pass a swift type as a function argument 3. Use append(contentsOf:) instead of foreach and append(_:) 4. Use extensions instead of global functions 5. This function will return an array of a specific elementType
Nice, case binding is very good syntax. You probably shouldn't be passing the Swift Type like that, it feels either redundant or unnecessary, looks like the return value can be inferred somehow instead. For appending, I'd go for the += operator, maybe its syntactic sugar. Anyhow a lot of good stuff, I'd have to make the video twice as long to include everything.
I simply used `result.reduce(0,+)` to see if it returns an [Int] or [Any]. It does not if you don't cast the result type for solutions unlike his one. When using "as! [Int]" on the result your program will crash when the type can't get casted (like one element in the [Any] is a String instead Int). His version will at least call the assertion and thus you could react on that. Still it is not a compile time error. I am not sure if inferring a return value actually is possible? I would be interested if you have a solution for that! I guess one would need a recursive datatype instead of [Any] to begin with.
I think the only possible way to infer the return type is to check if there's only one type T in this array's individual elements, and return [T] or just [Any]. Using "where" clauses seems to be impossible. But my solution above is more flexible. elementType can be default to Any.self, so when it takes no argument, it will acts like any other solutions. But if you have a intArray, you can still let it return an [Any].
I didn't do it in a loop and not sure if it's good func flatArray(input: [Any]) -> [Int] { if input.isEmpty {return [] } if input.first! is Int { return [input.first! as! Int ] + flatArray(input: Array(input.dropFirst())) } return flatArray(input: input.first! as! [Any] ) + flatArray(input: Array(input.dropFirst())) }
I think if this solution works, then it's fine. However, there are 3 different recursive calls in the logic. For anyone that isn't used to recursion, it's very difficult to understand how you arrived to this solution. Also it feels like there is some repetition between the two cases. There's definitely room for improvement here.
Here is mine: func flattenArray(nestedArray: [Any]) -> [Int] { var myFlattenedArray = [Int]() for element in nestedArray { if let element = element as? Int { myFlattenedArray.append(element) } else if let element = element as? [Any] { myFlattenedArray += flattenArray(nestedArray: element) } } return myFlattenedArray } I don't like using !'s, and I got rid of the second for loop.
For an array, there is a much simplier answer than multiple loops, you can do this in one loop. I would have told interviewer to get serious, this isn't a take home it's a one line command. Use regex. /-?[0-9]/g PCRE blows away any recursion.
Here is my optimized solution var resultArray = [Int]() func flattenArray (nestedArray: [Any]) -> [Int] { for num in nestedArray { if num is Int { resultArray.append(num as! Int) } else if num is [Any]{ flattenArray(nestedArray: num as! [Any]) } } return resultArray } let result = flattenArray(nestedArray: [1, [2, [3, 4, 5]]]) print ("\(result)")
That's good, that's my solution too. But this approach does not work as a stand-alone method even though it is efficient. You need an array declared outside of your flatten array method.
You can add the resultArray as an argument to the function (and also the recursive function call inside), should clear it up from the global scope it is currently in :)
Hey Brian!!! Firstly Greetings from India. Keep up the good work. Well may be you need a personal in room water cooler unit. Need help. Ohh ya and I have a query that if i want to develop a app and have its data in Excel or ,json file maybe. So how do I automate the data insertion in the 'xcdatamodeld' file. And that is before i run the app in the simulator or the iPhone even. Please make a short video of any tool or so which solves this problem. Its will be so painstaking task... :-( Found a utility named "Core Data Editor" which does not compile. But the github link shows its tutorials. However I am unable to compile it even. Hers the link - github.com/ChristianKienle/Core-Data-Editor
def flat(arr): res = [] def rec_flat(arr): for i in arr: if isinstance(i, list): rec_flat(i) else: res.append(i) rec_flat(arr) return res slight difference in my solution
Hey, I'm kinda new in JS and I was wondering what this line does exactly: " !value.length ? finalArr.push(value) : flatten(value, finalArr); " Does it check if the variable value has any length(exists) or? Thanks in advance, also pretty slick calling the function in between execution, I wonder if that's a recommended thing to do or not.
I overlooked the fact that !value.length would actually evaluate an empty array as true and push the empty array into finalArr. Because [ ].length is 0, and !0 is true. But the point was to check if value has the length property to distinguish between arrays and numbers. I should have written: value.length == undefined ? finalArr.push(value) : flatten(value, finalArr); The line is a shorthand if-else-statement. if (value.length == undefined) { finalArr.push(value); } else { flatten(value, finalArr); } Not sure what you mean by calling the function in between execution, this is how recursion works, by calling the function within itself.
You can use an if let to avoid casting to [Any] when you already checked that element is of type [Any]. Here's my code: import UIKit func flattenArray(array: [Any]) -> [Int] { var flatArray = [Int]() for element in array { if let i = element as? Int { flatArray.append(i) } else if let a = element as? [Any] { flatArray.append(contentsOf: flattenArray(array: a)) } } return flatArray } var result = flattenArray(array: [1]) print(result) result = flattenArray(array: [1, 2]) print(result) result = flattenArray(array: [1, [2]]) print(result) result = flattenArray(array: [1, [2, 3]]) print(result) result = flattenArray(array: [1, [2, [3, [4]]]]) print(result)
func flattArrayWithWhileLoop(_ originalArray: [Any]) -> [Int] { var referenceArray = originalArray while referenceArray.compactMap({$0 as? Int}).count != referenceArray.count { referenceArray.enumerated().forEach { (index, any) in if !(any is Int) { referenceArray.remove(at: index) (any as! [Any]).enumerated().forEach { (offset, value) in referenceArray.insert(value, at: index + offset) } } } } let finalResult = referenceArray.compactMap({$0 as? Int}) return finalResult } My best try to use while loop to solve the problem
func flattArrayWithWhileLoop(_ originalArray: [Any]) -> [Int] { var refArr = originalArray while refArr.compactMap({$0 as? Int}).count != refArr.count { for (index, any) in refArr.enumerated() where any as? Int == nil { refArr[index...index] = (any as! [Any])[...] } } return refArr as! [Int] } // I am taking two of your courses (AppStore, Tinder) and reading two books now, feeling that I am keep improving my coding skills //Thanks
Wow, I can't believe that on the top-right corner, the picture is taken in my hometown Yilan!!! Oh get back to this clip, great video. I happen to search for "flatten nested arrays" and your video showed up. Glad I came in to watch this vid.
You're awesome Brian, I love how you put emphasis on algorithms and logical thinking and not just on pure code production. As you said, most often we just c/p solutions from stackoverflow and adjust it here and there.
You are legitly the best code teacher on youtube. Love the explanation of logic that you go through. Definitely makes a difference when trying to learn.
Awesome demonstration..!! Thanks Brian. This is a very good video.
Great video! Question: in these interviews/ take home assignments is it acceptable to force unwrap optionals?
Never force unwrap, except if you want to come off super lazy
Bryant... you need to make more algorithm challenges. This is what makes a developer strong... libraries come and go bro
Thats why I rarely use libraries in these videos.
This video is really good, this is really the fun of programming when you solve problems like this!
I love these types of exercises. Most people that cannot solve these exercises usually cannot make it past interviews. These are just some of the problems we solve as software engineers, so for people that don't enjoy it, it'll be hard to enjoy programming.
Superb brian.. i have an doubt at which sinario will use this type of algarith
And can u make an video on expandable collectionview
Initially all cell are in collapsed state... i mean we need to show only sections intially...
After clicking any one of the section should expand items corresponding section....
If i click another section previous section should be closed. And selected section should expand
Thank you brian
Super Brian. Will you make video on Any and Any object
Perhaps one day, but these abstract concepts are kind of difficult to explain. I think Apple's documentation is really good for this.
Great video and explanation! I really like how you build out your videos with excellent examples and increasing difficulties :-)
Thanks, it's really difficult to tackle these challenges if you start from a very difficult use case. Similar to whiteboarding exercises, you should always begin with the most basic example of your inputs.
Hey Brian.. Pretty good stuff. I was able to before it out before watching the video although it took me an hour to do so.
One thing I would suggest is in else if element is [Any], we don't need that as we already know if element is not Int it will be Any only. So its kind of ambiguous calling. Also, inside else if we are again saying element is Any.
So, writing else only will work perfectly!
Thank you for this video. Need more like this please.
Awesome video! You're an awesome teacher! Thank you so much for doing these!
Great video! Keep up the good work!
i got deeply for recursion, you are so awesome, thank you alot
Really liked this vid!! Good stuff
Hi Brian.I am thinking about buying your instagran course.is it done programmatically or do you use storyboard? and is it for swift 4?thank you
Hey Eduardo, every course is done programmatically, this way students understand exactly whats going on. Videos 1-40 are recorded in Swift 3, 41-47 are in Swift 4. Each lesson comes with source code that you can compile in Swift 3 and Swift 4, so don't worry if anything goes wrong, which is pretty rare since Swift 4 syntax changes are minor.
Hi I know it has been a while but I just found this video. Instead of creating an extra variable of recursionResult and that for loop, I just wrote "myFlatenedArray += flatenArray(element as! [Any])". It seems simpler, but I am wondering, is there a difference between appending an array to another with for loop vs using the + to merge two arrays? Would there be a time difference, or are they actually the same?
This really helped me understand a problem I recently did! I used the JS flat() method, but this makes sense too.
Hi Brian, Can you please help? I don't understand one thing: when the recursion calls, flattenArray(nestedArray: element as! [Any]), will " var myFlattenedArray = [Int]() " be called every time? Like the example with [1, [2]], when flattenArray(nestArray: [2]) calls, if " var myFlattenedArray = [Int]() " is called, then myFlattenedArray will be empty. Thanks a lot! Mike
Another great video! Thank you broski!
This was very helpful, thanks so much!
Does Swift support tail optimization? If it does you can use it to optimize your solution further.
I really liked this one!
Thanks again for Swift coding algorithm practice. Good review of recursion. Any more greatly appreciated!
Hey, it is great, can you tell me the complexity of your algorithm? and also it would be really helpful if you could talk and give some examples of using "FlattenBidirectionalCollection"
func testy(holder: Array) -> Array {
for x in holder {
if x is [Any] {
testy(holder: x as! Array)
} else {
holdy.append(x)
}
}
return holdy
}
This is what I came up with, but it seems a little different. I didn't set the recalled function to anything; I just called it. Also, I never checked for the type, I simply made sure it would handle anything that wasn't itself an array of any type. Would this approach present any issues?
Flatmap, higher order function also can help for this?
Hello Sir I am Shailesh My question is How we get update if any contact is added in iPhone than update that contact number to the server how develop that code in swift 3
Awesome as always, learn so much by trying to do it first then following to see how you did it differently, one quick question, why do you say 'bang' for '!' ?
Also is it quicker to add the arrays together instead of doing another for loop to append:
myFlattenedArray += flattenArray(nestedArray: element as! [Any])
Thanks!
! is often called 'bang' in software development. I originally used += on the recursive result but I thought it would be confusing to show this new bit of code.
I think this could be even neater with an extension of Array;
extension Array {
func flatten() -> [Any] {
var result = [Any]()
for obj in self {
if let cast = obj as? [Any] {
result.append(contentsOf: cast.flatten())
} else {
result.append(obj)
}
}
return result
}
}
let arr: [Any] = [0, 1, [2, [3, 4]]]
let arr2: [Any] = [0, 1, 2, 3, [4]]
print(arr.flatten())
print(arr2.flatten())
So you're allowed to use existing libraries? I always thought I'd have to write the mechanisms manually
Dr1zak haha. You just new in programming. Never create thing that already exist. Never recreate a bicycle. Always use libraries. Always use that already exist. Even Uber, Instagram use same libraries as we. For example dagger 2, retrofit, rxjava, retrofit. Everyone use libraries. Even big companies as Uber. Hope I gave you some path for growing in world of programming
In python3, it can be done like below:
List = [ ]
def flatten(x):
for i in x:
if isinstance(i,int):
List.append(i)
elif isinstance(i,list):
flatten(i)
return List
print(flatten(x))
Wow! Awesome
I've done almost the same code!
def flatter(input_list,x=[]):
for item in input_list:
if not isinstance(item, list):
x.extend([item])
else:
flatter(item,x)
return x
z=[3,4,9,0, [6,8,[8,9,[99,5],[999,123]]],8]
print(flatter(z) )
Why don’t you use “if let” syntax?
Brian I need your help! I have a great idea for an app, but I'm torn on what platform to make it on (android or iOS). I have never developed for either of them so I am a very huge noob! I looked at android studio but I got very intimidated by the look and feel of android studio, but i can't say Xcode feels more comfortable because never used it. And also to mention, I have barely any experience in java but I have a great understanding of c++. Also I have a windows computer so if I should develop for iOS I would either have to buy a Mac or make my co punter a hackintosh. So in my situation, what would you recommend I do?
Android is the easiest route. Transitioning to Java from C++ is probably easier instead of C++ => Swift. And then you have the hackintosh issues and it should be a no-brainer by now...
Easy answer, use whatever you can get your hands on.
Lets Build That App ok thankyou! Will there be more tutorials on android development from you in the future?
+Lets Build That App nice video and solution!
What do you think of the following approach:
func flatten(_ arr: [Any]) -> [Int] {
guard !arr.isEmpty else { return [] }
let queue = arr.count > 1 ? Array(arr[1...arr.count-1]) : []
if let num = arr.first as? Int {
return [num] + flatten(queue)
}
return flatten(arr.first as? [Any] ?? []) + flatten(queue)
}
Hello! Why won't you use "appendContentsOf" instead of iterating and appending each element in the second (else if) block of code? Thanks in advance
what does appendContentsOf do different than just appending a variable?
Alexandr Polienko bruh is it c language
I guess in that case you can avoid another "for loop", you write less code, it is easier to read and maintain + I think it might work faster, than looping through each element and appending it. It seems to be not important at all, but when we deal with really large arrays with tons of elements, then every half of a second might count. Just thinking ^_^
Nope, swift 3
append(contentsOf: Sequence) appends all the elements of a sequence. It just reduces the number of lines of code and Apple might have some tricks to making it more efficient.
I think this algorithm will be more flexible if we will use generic type instead of Int type. It will be great if Brian will update this lesson with Generic implementation )
Definitely it would be much better with generics, go ahead and give it a try.
let array = [["Hello", ["there", 3, 4], 4, "Whats up", 6, [3, 4, 4]], 3] as [Any]
func flattenArray(_ array:[T]) -> [T] {
var finalFlatArray:[T] = []
for idx in 0..
let my = [[[["binay"]]],[45],454,3,["dell",["car","sun"]]] as Array
func myFlatArryWithVal( _ myArrVal: [Any]) -> [Any] {
var myArr = [Any]()
for elements in myArrVal{
if (elements is Array){
let res = myFlatArryWithVal(elements as! [Any] )
for res2 in res{
myArr.append(res2)
}
}else{
myArr.append(elements )
}
}
return myArr
}
print(myFlatArryWithVal(my))
output
["binay", 45, 454, 3, "dell", "car", "sun"]
hey brn. when you live again ,,,, we are waiting
still.................................
You want to watch another live stream? I might do another one in 2 weeks.
Hi Brian. Nice vid
How do you do this in C
Fun video~!
Hey Brian! I'm a college student currently taking games development in which I learn some programming languages ( C# and GML ) and also learn aspects of design such as 3D modelling and UI. I wish to proceed into university to get a masters degree in software or mobile app engineering. Is it worth it? Will my salary be much greater and will it be better off in the long run to proceed to achieve my masters at the expense of around about $45,000 of student loans for that extra degree? :D Thanks. Hope you reply!
Hi. How is it possible that's you can call in function flattenArray, inside itself (the recursion part at line 15) and use element as! [Any] as the argument for func flattenArray? That's like trying to eating a bread before you even got to buy the bread. Thanks. God bless, Proverbs 31
he's basically passing the current index of the array, and the index is an array so he's casting as an array of type any and then performing the same process on that index of type array; basically check if the values are of type int and then appending to the result. If at any point there aren't any objects of type array then it doesn't satisfy the condition on line 13 and just simply returns the result.
When I saw this I thought of flatMap in functional programming.
That was my attempt
def flatter(input_list,x=[]):
for item in input_list:
if not isinstance(item, list):
x.extend([item])
else:
flatter(item,x)
return x
z=[3,4,9,0, [6,8,[8,9,[99,5],[999,123]]],8]
print(flatter(z) )
I faced this task in my first interview.
here is another solution that I thought was a little more elegant:
func flattenArray(array: [Any]) -> [Any] {
var final:[Int] = []
array.forEach { i in
if let arr = i as? [Any] {
final.append(contentsOf: flattenArray(array: arr) as! [Int])
} else {
final.append(i as! Int)
}
}
return final
}
you could also make this an extension to array so that it works for all types of arrays
Te pasaste, chino.
Waiting for next video in android series ... 😅😅😅
hey ..., you know its not ""morning" everywhere in the world right xD (10:45pm here)
Great
please use kotlin for next coding videos
Hey brain, greetings from China.
My solution with generics:
extension Array {
static func flatten(_ array: [Any], elementType: E.Type) -> [E] {
var result = [E]()
for item in array {
switch item {
case let nestedArray as [Any]:
result.append(contentsOf: flatten(nestedArray, elementType: elementType))
case let individual as E:
result.append(individual)
default:
assert(false, "Element type does not match.")
}
}
return result
}
}
extension Array where Element == Any {
func flattened(elementType: E.Type) -> [E] {
return Array.flatten(self, elementType: elementType)
}
}
Usage:
let intArray = [1, [2, [3, [4, [5, 6, 7]]]]] as [Any]
intArray.flattened(elementType: Int.self) // [1, 2, 3, 4, 5, 6, 7]
let stringArray = ["a", "b", ["c", [], [["d"]]]] as [Any]
stringArray.flattened(elementType: String.self) // ["a", "b", "c", "d"]
let mixedArray = ["你好", "谢谢", 123, [4, "再见", [], [[567, ""]]]] as [Any]
mixedArray.flattened(elementType: Any.self) // ["你好", "谢谢", 123, 4, "再见", 567, ""]
Some tips here:
1. Use switch statement for type casting
2. Pass a swift type as a function argument
3. Use append(contentsOf:) instead of foreach and append(_:)
4. Use extensions instead of global functions
5. This function will return an array of a specific elementType
Nice, case binding is very good syntax. You probably shouldn't be passing the Swift Type like that, it feels either redundant or unnecessary, looks like the return value can be inferred somehow instead.
For appending, I'd go for the += operator, maybe its syntactic sugar.
Anyhow a lot of good stuff, I'd have to make the video twice as long to include everything.
I simply used `result.reduce(0,+)` to see if it returns an [Int] or [Any]. It does not if you don't cast the result type for solutions unlike his one. When using "as! [Int]" on the result your program will crash when the type can't get casted (like one element in the [Any] is a String instead Int). His version will at least call the assertion and thus you could react on that. Still it is not a compile time error. I am not sure if inferring a return value actually is possible? I would be interested if you have a solution for that! I guess one would need a recursive datatype instead of [Any] to begin with.
I think the only possible way to infer the return type is to check if there's only one type T in this array's individual elements, and return [T] or just [Any]. Using "where" clauses seems to be impossible.
But my solution above is more flexible. elementType can be default to Any.self, so when it takes no argument, it will acts like any other solutions. But if you have a intArray, you can still let it return an [Any].
I didn't do it in a loop and not sure if it's good
func flatArray(input: [Any]) -> [Int] {
if input.isEmpty {return [] }
if input.first! is Int {
return [input.first! as! Int ] + flatArray(input: Array(input.dropFirst()))
}
return flatArray(input: input.first! as! [Any] ) + flatArray(input: Array(input.dropFirst()))
}
I think if this solution works, then it's fine. However, there are 3 different recursive calls in the logic. For anyone that isn't used to recursion, it's very difficult to understand how you arrived to this solution. Also it feels like there is some repetition between the two cases. There's definitely room for improvement here.
Here is mine:
func flattenArray(nestedArray: [Any]) -> [Int] {
var myFlattenedArray = [Int]()
for element in nestedArray {
if let element = element as? Int {
myFlattenedArray.append(element)
} else if let element = element as? [Any] {
myFlattenedArray += flattenArray(nestedArray: element)
}
}
return myFlattenedArray
}
I don't like using !'s, and I got rid of the second for loop.
Cool, looks very similar to my original solution.
Hi. There's so many Inception movie like elements in programming and Swift. God bless, Proverbs 31
Taiwan_traveller?! awesome!!!
For an array, there is a much simplier answer than multiple loops, you can do this in one loop. I would have told interviewer to get serious, this isn't a take home it's a one line command. Use regex. /-?[0-9]/g PCRE blows away any recursion.
array inside of an array.. arrayception
Here is my optimized solution
var resultArray = [Int]()
func flattenArray (nestedArray: [Any]) -> [Int] {
for num in nestedArray {
if num is Int {
resultArray.append(num as! Int)
}
else if num is [Any]{
flattenArray(nestedArray: num as! [Any])
}
}
return resultArray
}
let result = flattenArray(nestedArray: [1, [2, [3, 4, 5]]])
print ("\(result)")
That's good, that's my solution too. But this approach does not work as a stand-alone method even though it is efficient. You need an array declared outside of your flatten array method.
u can't get any optimization with this solution, but somewhere in code u can change the resultArray by mistake. bad solution
You can add the resultArray as an argument to the function (and also the recursive function call inside), should clear it up from the global scope it is currently in :)
You are doing the same !
Hey Brian!!! Firstly Greetings from India. Keep up the good work. Well may be you need a personal in room water cooler unit. Need help. Ohh ya and I have a query that if i want to develop a app and have its data in Excel or ,json file maybe. So how do I automate the data insertion in the 'xcdatamodeld' file. And that is before i run the app in the simulator or the iPhone even. Please make a short video of any tool or so which solves this problem. Its will be so painstaking task... :-( Found a utility named "Core Data Editor" which does not compile. But the github link shows its tutorials. However I am unable to compile it even. Hers the link - github.com/ChristianKienle/Core-Data-Editor
Brian. That is Cool.
Python3 recursion answer:
intArray = [[3,0],1,2,[3,4,[5,6,[7,8]]]]
stringArray = [["meh meh", "meeee"], "hello", ["world", "world", ["how", "is", "it"]]]
mixedArray = [["zero"], 1, 2, ["three", "four", {"mrobject": "equals five", "mrintinobject": 5}], 0, 0, 0, 0]
def flattenArray(outerArray):
flatten = []
def flatternizer(innerArray):
if isinstance(innerArray, list):
for elem in innerArray:
flatternizer(elem)
else:
flatten.append(innerArray)
return innerArray
flatternizer(outerArray)
return flatten
print(flattenArray(intArray))
print(flattenArray(stringArray))
print(flattenArray(mixedArray))
def flat(arr):
res = []
def rec_flat(arr):
for i in arr:
if isinstance(i, list):
rec_flat(i)
else:
res.append(i)
rec_flat(arr)
return res
slight difference in my solution
Much easier with Javascript :3
let flatten = function (arr, finalArr) {
finalArr = finalArr || [];
arr.forEach(value => {
!value.length ? finalArr.push(value) : flatten(value, finalArr);
});
return finalArr;
};
let nested = [1, 2, [[[3]]], [42, [600, 400, 200]]];
let flat = flatten(nested); // [1, 2, 3, 42, 600, 400, 200]
Hey, I'm kinda new in JS and I was wondering what this line does exactly:
" !value.length ? finalArr.push(value) : flatten(value, finalArr); "
Does it check if the variable value has any length(exists) or?
Thanks in advance, also pretty slick calling the function in between execution, I wonder if that's a recommended thing to do or not.
I overlooked the fact that !value.length would actually evaluate an empty array as true and push the empty array into finalArr. Because [ ].length is 0, and !0 is true. But the point was to check if value has the length property to distinguish between arrays and numbers. I should have written:
value.length == undefined ? finalArr.push(value) : flatten(value, finalArr);
The line is a shorthand if-else-statement.
if (value.length == undefined) { finalArr.push(value); }
else { flatten(value, finalArr); }
Not sure what you mean by calling the function in between execution, this is how recursion works, by calling the function within itself.
I think this is a better solution :
function flatten(arr) {
return arr.reduce(
(flat, toFlatten) =>
flat.concat(Array.isArray(toFlatten)
? flatten(toFlatten)
: toFlatten), []
)
}
console.log(flatten([0, 1, [2, [3, 4]]]))
Cool! I've never had to use reduce before. You just gave me the perfect excuse to learn more about it :)
ES6 Syntax for flatenning an Array:
const flat = [1, 2, [[[3]]], [42, [600, 400, 200]]].reduce( (a,b) => a.concact(b), [])
You can use an if let to avoid casting to [Any] when you already checked that element is of type [Any]. Here's my code:
import UIKit
func flattenArray(array: [Any]) -> [Int] {
var flatArray = [Int]()
for element in array {
if let i = element as? Int {
flatArray.append(i)
} else if let a = element as? [Any] {
flatArray.append(contentsOf: flattenArray(array: a))
}
}
return flatArray
}
var result = flattenArray(array: [1])
print(result)
result = flattenArray(array: [1, 2])
print(result)
result = flattenArray(array: [1, [2]])
print(result)
result = flattenArray(array: [1, [2, 3]])
print(result)
result = flattenArray(array: [1, [2, [3, [4]]]])
print(result)
your code doesn't even compile
Thank you. I fixed it.
just converted it to javascript cos why not?
function flattenArray(a=[]){
var temp = [];
for(var i =0; i
just press f12 and paste to console to check it out
Looks ok, seems like an n squared nested for loop which is a bad idea.
My result:
func flatten(array: [Any]) -> [Int] {
var flattenItems = [Int]()
for item in array {
if item is Int {
flattenItems.append(item as! Int)
} else {
flattenItems += flatten(array: item as! [Any])
}
}
return flattenItems
}
func flattArrayWithWhileLoop(_ originalArray: [Any]) -> [Int] {
var referenceArray = originalArray
while referenceArray.compactMap({$0 as? Int}).count != referenceArray.count {
referenceArray.enumerated().forEach { (index, any) in
if !(any is Int) {
referenceArray.remove(at: index)
(any as! [Any]).enumerated().forEach { (offset, value) in
referenceArray.insert(value, at: index + offset)
}
}
}
}
let finalResult = referenceArray.compactMap({$0 as? Int})
return finalResult
}
My best try to use while loop to solve the problem
Cool, I believe there are a lot of different solutions to this problem. Glad you were able to find your own algorithm.
func flattArrayWithWhileLoop(_ originalArray: [Any]) -> [Int] {
var refArr = originalArray
while refArr.compactMap({$0 as? Int}).count != refArr.count {
for (index, any) in refArr.enumerated() where any as? Int == nil {
refArr[index...index] = (any as! [Any])[...]
}
}
return refArr as! [Int]
}
// I am taking two of your courses (AppStore, Tinder) and reading two books now, feeling that I am keep improving my coding skills
//Thanks