Duplicate Int in Array , Dictionary or Set in SWIFT - arrays

Reading up on Sets and Arrays I find that a Set cannot, or is not able to store duplicate values ( Ints, Strings, etc ).
Knowing this, if we are to solve for finding a duplicate Int in an array and one method is to convert the Array to a Set, how come we don't get an error once the Array is a Set?
The methods below simply return a Bool value if the array contains duplicates.
import UIKit
func containsDuplicatesDictionary(a: [Int]) -> Bool {
var aDict = [Int : Int]()
for value in a {
if let count = aDict[value] {
aDict[value] = count + 1
return true
} else {
aDict[value] = 1
}
}
return false
}
containsDuplicatesDictionary(a: [1,2,2,4,5])
func containsDuplicatesSet(a: [Int]) -> Bool {
return Set(a).count != a.count
}
containsDuplicatesSet(a: [1,2,2,4])
The first function, containsDuplicatesDictionary, I convert the array to a Dictionary, of course this takes a for loop as well. The Set method can be done in one line, which is really nice. But I guess since I am new to this, I would think converting the array would throw an error immediately since theres duplicate values.
What am I missing when it's converted
Thank you.

Set, by design is an unordered, unique collection of elements. The implementation of Set takes care of duplicate values itself, when you try to add a duplicate value, it checks whether the value is already present in the Set or not and if it is, the value is not added.
When you call the initializer of Set that takes a sequence as its input parameter (this is what you use when writing Set(a), where a is of type [Int], under the hood, the initializer adds the elements one by one checking whether any of the new elements are already present in the Set or not.
You could make a custom initializer method for Set that would throw an error if you would try to add a duplicate value to it, but it wouldn't really have any advantages for any users of Swift, hence the current implementation that just doesn't add the value if it is already present in the Set and doesn't throw an error. This way, you can safely and easily get rid of any duplicates in a non-unique collection of elements (such as an array).

Related

swift: extend array comparability

In swift 4 arrays are automatically comparable - but they check each element sequentially. Does element 1 match element 1, element 2 match element 2, etc.? - which is probably good standard behaviour.
But I'd like to extend / change this behaviour for a certain type Interval, so it doesn't matter what the order is of the elements, as long as the contents of the two arrays match. i.e. if both the arrays are sorted and match (using the original behaviour) then that should trigger comparable.
The trouble is, by defining my new behaviour, I 'override' and lose the existing behaviour (which I'd like ideally to keep so I can test once both arrays are sorted) - and so I get a warning 'All paths through this function will call itself'. Any ideas how to solve please
extension Array where Element == Interval {
static func == (lhs: [Interval], rhs: [Interval]) -> Bool {
return lhs.sorted() == rhs.sorted()
}
}
First make Interval conform to Hashable. Now you can coerce the arrays to Sets and compare for equality without order mattering.

Map in order range loop

I'm looking for a definitive way to range over a Go map in-order.
Golang spec states the following:
The iteration order over maps is not specified and is not guaranteed to be the same from one iteration to the next. If map entries that have not yet been reached are removed during iteration, the corresponding iteration values will not be produced. If map entries are created during iteration, that entry may be produced during the iteration or may be skipped. The choice may vary for each entry created and from one iteration to the next. If the map is nil, the number of iterations is 0.
All I've found here on StackOverflow and Googling are (imho) workarounds that I don't like.
Is there a solid way to iterate through a map and retrieve items in the order they've been inserted?
The solutions I've found are:
Keep track of keys and values in two separate slices: which sounds like "Do not use a map", losing all the advantages of using maps.
Use a map but keep track of keys in a different slice: this means data duplication which might lead to data misalignment and eventually may bring loads of bugs and painful debugging.
What do you suggest?
Edit in response to the possible duplicate flag.
There's a slight difference between my question and the one provided (this question, but also this one), both questions asked for looping through the map following the keys lexicographic order; I, instead, have specifically asked:
Is there a solid way to iterate through a map and retrieve items in the order they've been inserted?
which is not lexicographic and thus different from #gramme.ninja question:
How can I get the keys to be in order / sort the map so that the keys are in order and the values correspond?
If you need a map and keys in order, those are 2 different things, you need 2 different (data) types to provide that functionality.
With a keys slice
The easiest way to achieve this is to maintain key order in a different slice. Whenever you put a new pair into the map, first check if the key is already in it. If not, add the new key to the separate slice. When you need elements in order, you may use the keys slice. Of course when you remove a pair, you also have to remove it from the slice too.
The keys slice only has to contain the keys (and not the values), so the overhead is little.
Wrap this new functionality (map+keys slice) into a new type and provide methods for it, and hide the map and slice. Then data misalignment cannot occur.
Example implementation:
type Key int // Key type
type Value int // Value type
type Map struct {
m map[Key]Value
keys []Key
}
func New() *Map {
return &Map{m: make(map[Key]Value)}
}
func (m *Map) Set(k Key, v Value) {
if _, ok := m.m[k]; !ok {
m.keys = append(m.keys, k)
}
m.m[k] = v
}
func (m *Map) Range() {
for _, k := range m.keys {
fmt.Println(m.m[k])
}
}
Using it:
m := New()
m.Set(1, 11)
m.Set(2, 22)
m.Range()
Try it on the Go Playground.
With a value-wrapper implementing a linked-list
Another approach would be to wrap the values, and –along the real value– also store the next/previous key.
For example, assuming you want a map like map[Key]Value:
type valueWrapper struct {
value Value
next *Key // Next key
}
Whenever you add a pair to the map, you set a valueWrapper as the value, and you have to link this to the previous (last) pair. To link, you have to set next field of the last wrapper to point to this new key. To easily implement this, it's recommended to also store the last key (to avoid having to search for it).
When you want to iterate over the elements in insertion order, you start from the first (you have to store this), and its associated valueWrapper will tell you the next key (in insertion order).
Example implementation:
type Key int // Key type
type Value int // Value type
type valueWrapper struct {
v Value
next *Key
}
type Map struct {
m map[Key]valueWrapper
first, last *Key
}
func New() *Map {
return &Map{m: make(map[Key]valueWrapper)}
}
func (m *Map) Set(k Key, v Value) {
if _, ok := m.m[k]; !ok && m.last != nil {
w2 := m.m[*m.last]
m.m[*m.last] = valueWrapper{w2.v, &k}
}
w := valueWrapper{v: v}
m.m[k] = w
if m.first == nil {
m.first = &k
}
m.last = &k
}
func (m *Map) Range() {
for k := m.first; k != nil; {
w := m.m[*k]
fmt.Println(w.v)
k = w.next
}
}
Using it is the same. Try it on the Go Playground.
Notes: You may vary a couple of things to your liking:
You may declare the internal map like m map[Key]*valueWrapper and so in Set() you can change the next field without having to assign a new valueWrapper.
You may choose first and last fields to be of type *valueWrapper
You may choose next to be of type *valueWrapper
Comparison
The approach with an additional slice is easier and cleaner. But removing an element from it may become slow if the map grows big, as we also have to find the key in the slice which is "unsorted", so it's O(n) complexity.
The approach with linked-list in value-wrapper can easily be extended to support fast element removal even if the map is big, if you also add the prev field to the valueWrapper struct. So if you need to remove an element, you can super-fast find the wrapper (O(1)), update the prev and next wrappers (to point to each other), and perform a simple delete() operation, it's O(1).
Note that deletion in the first solution (with slice) could still be sped up by using 1 additional map, which would map from key to index of the key in the slice (map[Key]int), so delete operation could still be implemented in O(1), in exchange for greater complexity. Another option for speeding up could be to change the value in the map to be a wrapper, which could hold the actual value and the index of the key in the slice.
See related question: Why can't Go iterate maps in insertion order?

What is the difference between ArrayBuffer and Array

I'm new to scala/java and I have troubles getting the difference between those two.
By reading the scala doc I understood that ArrayBuffer are made to be interactive (append, insert, prepend, etc).
1) What are the fundamental implementation differences?
2) Is there performance variation between those two?
Both Array and ArrayBuffer are mutable, which means that you can modify elements at particular indexes: a(i) = e
ArrayBuffer is resizable, Array isn't. If you append an element to an ArrayBuffer, it gets larger. If you try to append an element to an Array, you get a new array. Therefore to use Arrays efficiently, you must know its size beforehand.
Arrays are implemented on JVM level and are the only non-erased generic type. This means that they are the most efficient way to store sequences of objects – no extra memory overhead, and some operations are implemented as single JVM opcodes.
ArrayBuffer is implemented by having an Array internally, and allocating a new one if needed. Appending is usually fast, unless it hits a limit and resizes the array – but it does it in such a way, that the overall effect is negligible, so don't worry. Prepending is implemented as moving all elements to the right and setting the new one as the 0th element and it's therefore slow. Appending n elements in a loop is efficient (O(n)), prepending them is not (O(n²)).
Arrays are specialized for built-in value types (except Unit), so Array[Int] is going to be much more optimal than ArrayBuffer[Int] – the values won't have to be boxed, therefore using less memory and less indirection. Note that the specialization, as always, works only if the type is monomorphic – Array[T] will be always boxed.
The one other difference is, Array's element created as on when its declared but Array Buffer's elements not created unless you assign values for the first time.
For example. You can write Array1(0)="Stackoverflow" but not ArrayBuffer1(0)="Stackoverflow" for the first time value assignments.
(Array1 = Array variable & ArrayBuffer1 = ArrayBuffer variable)
Because as we know, Array buffers are re-sizable, so elements created when you insert values at the first time and then you can modify/reassign them at the particular element.
Array:
Declaring and assigning values to Int Array.
val favNums= new Array[Int](20)
for(i<-0 to 19){
favNums(i)=i*2
}
favNums.foreach(println)
ArrayBuffer:
Declaring and assigning values to Int ArrayBuffer.
val favNumsArrayBuffer= new ArrayBuffer[Int]
for(j<-0 to 19){
favNumsArrayBuffer.insert(j, (j*2))
//favNumsArrayBuffer++=Array(j*3)
}
favNumsArrayBuffer.foreach(println)
If you include favNumsArrayBuffer(j)=j*2 at the first line in the for loop, It doesn't work. But it works fine if you declare it in 2nd or 3rd line of the loop. Because values assigned already at the first line now you can modify by element index.
This simple one-hour video tutorial explains a lot.
https://youtu.be/DzFt0YkZo8M?t=2005
Use an Array if the length of Array is fixed, and an ArrayBuffer if the length can vary.
Another difference is in term of reference and value equality
Array(1,2) == Array(1,2) // res0: Boolean = false
ArrayBuffer(1, 2) == ArrayBuffer(1,2) // res1: Boolean = true
The reason for the difference is == routes to .equals where Array.equals is implemented using Java's == which compares references
public boolean equals(Object obj) {
return (this == obj);
}
whilst ArrayBuffer.equals compares elements contained by ArrayBuffer using sameElements method
override def equals(o: scala.Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (
o match {
case it: Seq[A] => (it eq this) || (it canEqual this) && sameElements(it)
case _ => false
}
)
Similarly, contains behaves differently
Array(Array(1,2)).contains(Array(1,2)) // res0: Boolean = false
ArrayBuffer(ArrayBuffer(1,2)).contains(ArrayBuffer(1,2)) // res1: Boolean = true

Swift Dictionary lookup causing compile-time error

I'm dipping my toe into Swift, but have run into an issue that has me slightly confused. Given an integer index I'm trying to fetch the corresponding key of a Dictionary and return the value associated with it.
Using the following structure as an example:
Class CustomClass {
private var collection: [String: [SifterIssue]] = ["MyStringKey": [MyCustomCollectionClass]()]
/* ... */
}
I tried to solve the problem like so:
var keys = Array(self.collection.keys)
var key: String = keys[section] as String
return self.collection[key].count // error is flagged here
But found that this results in a compiler error, which states that 'String' is not convertible to 'DictionaryIndex'. Stumped, I tried a slightly more verbose solution and was surprised to find that this compiled and worked without issue.
var keys = Array(self.collection.keys)
var key: String = keys[section] as String
var collection: [MyCustomCollectionClass] = self.collection[key]! as [MyCustomCollectionClass]
return issues.count
Can anyone explain to me why the first solution refuses to compile?
As #Zaph said, ignoring potential fatal errors is a bad idea and it's something that swift was, in part, designed to help with. This is the most "swifty" code I could come up:
func collectionCount(#section: Int) -> Int? {
switch section {
case 0..<collection.count: // Make sure section is within the bounds of collection's keys array
let key = collection.keys.array[section] // Grab the key from the collection's keys array
return collection[key]!.count // We can force unwrap collection[key] here because we know that key exists in collection
default:
return nil
}
}
It uses the range/pattern matching feature of swift's switch statement to make sure that section in the bounds of collection's keys array; that felt more "swifty" than using if, mainly because I couldn't find a way to use swift's Range in an if statement. It also uses collection.keys lazy property array as a shortcut instead of creating a new Array with Array(collection.keys). Since we've already made sure that section is within the bounds of collection.keys, we can forcibly unwrap collection[key]! when we get its count.
Just for fun, I also made a generic function that takes a collection as input to generalize things:
func collectionCount<T,U>(#collection: [T:[U]], #section: Int) -> Int? {
switch section {
case 0..<collection.count: // Make sure section is within the bounds of collection's keys array
let key = collection.keys.array[section] // Grab the key from the collection's keys array
return collection[key]!.count // We can force unwrap collection[key] here because we know that key exists in collection
default:
return nil
}
}
[T:[U]] basically says that collection needs to be a Dictionary with key T whose values are an Array of U.
Ignoring the fatal potential error is a really bad idea. The whole reason for Optionals is to prevent crashes at runtime.
func collectionCount(#section: Int) -> Int? {
var keys = Array(self.collection.keys)
if section < keys.count {
var key = keys[section] as String
println("key: \(key)")
return self.collection[key]!.count
}
else {
// handle error here
return nil
}
}
Throwing in "!" unwrapping without knowing that the value can never be nil is much worse than the Objective-C handling of nil. If this becomes the standard way of handling Optionals by a substantial number of developers Swift will be a disaster. Please do not do this.

Swift: optional array count

In Objective-C, if I had the following property:
#property (strong, nonatomic) NSArray * myArray;
A method to return a number of objects in myArray would look like:
- (NSInteger) numberOfObjectsInMyArray
{
return [self.myArray count];
}
This would return either the number of objects in the array, or 0 if myArray == nil;
The best equivalent I can think of for doing this in Swift is:
var myArray: Array<String>?
func numberOfObjectsInMyArray() -> Int
{
return myArray ? myArray!.count : 0
}
So checking the optional array contains a value, and if so unwrap the array and return that value, otherwise return 0.
Is this the correct way to do this? Or is there something simpler?
Try using the nil coalescing operator.
According to the Apple Documentation:
The nil coalescing operator (a ?? b) unwraps an optional a if it contains a value, or returns a default value b if a is nil.
So your function could look like this:
func numberOfObjectsInMyArray() -> Int {
return (myArray?.count ?? 0)
}
I agree with others that this could be a bad idea for a number of reasons (like making it look like there is an array with a count of "0" when there isn't actually an array at all) but hey, even bad ideas need an implementation.
EDIT:
So I'm adding this because two minutes after I posted this answer, I came across a reason for doing exactly what the author wants to do.
I am implementing the NSOutlineViewDataSource protocol in Swift. One of the functions required by the protocol is:
optional func outlineView(_ outlineView: NSOutlineView,
numberOfChildrenOfItem item: AnyObject?) -> Int
That function requires that you return the number of children of the item parameter. In my code, if the item has any children, they will be stored in an array, var children: [Person]?
I don't initialize that array until I actually add a child to the array.
In other words, at the time that I am providing data to the NSOutlineView, children could be nil or it could be populated, or it could have once been populated but subsequently had all objects removed from it, in which case it won't be nil but it's count will be 0. NSOutlineView doesn't care if children is nil - all it wants to know is how many rows it will need to display the item's children.
So, it makes perfect sense in this situation to return 0 if children is nil. The only reason for calling the function is to determine how many rows NSOutlineView will need. It doesn't care whether the answer is 0 because children is nil or because it is empty.
return (children?.count ?? 0) will do what I need. If children is nil it will return 0. Otherwise it will return count. Perfect!
That looks like the simpler way.
The Objective-C code is shorter only because nil is also a form of 0, being a C-based language.
Since swift is strongly typed you don't have such a shorthand. In this specific case it requires a little more effort, but in general it saves you most of the headaches caused by loose typing.
Concerning the specific case, is there a reason for making the array optional in the first place? You could just have an empty array. Something like this might work for you:
var myArray: Array<String> = []
func numberOfObjectsInMyArray() -> Int {
return myArray.count
}
(Source for this information)
How about using optional for return value?
var myArray: Array<String>?
func numberOfObjectsInMyArray() -> Int? {
return myArray?.count
}
I think that this way is safer.
(Source for this information)

Resources