Can I determine how many times it is duplicated from the Swift array and output the number of times it is duplicated?
For example, if there is an array called [0,0,0,2,2,3,4,4],
0—Three times.
1:0 times
2—Two times
3: Once
4: Twice
[0,2,4,3] // More duplicates
Is it possible to print like this?
Please let me know if there is a way to do it
Use NSCountedSet
let a=[0,0,0,2,2,3,4,4]
let counter = NSCountedSet (array:a)
let counts = [0,1,2,3,4].map {($0, counter.count(for:$0))}
counts.forEach {print("\($0.0):\($0.1)times")}
print(counts.sorted(by:{l,rinl.1>r.1}).map({$0.0}))
As Swift was named, it seems that you don't just want to listen to general algorithms, so I wrote to make the most of Swift's Collection
type of functionality.
Use Dictionary<T, Int>
([T:Int]
) to retain the results, where T
is the elemental type of the original array.Now it's T=Int
, so it looks like this.
In the past, Swift(<4.0) had to check if it was already in the Dictionary
, so the code became complicated where it wasn't essential, but now it has subscript(_:default:)
, so it's refreshing.
letarr=[0,0,0,2,2,3,4,4]
// Count the duplicate elements of the array
varnumToCount: Int:Int = [:]
US>for alt in ar {
numToCount [elt, default:0] + = 1
}
print(numToCount)//-> [2:2, 0:3, 3:1, 4:2]
As you can see, the resulting Dictionary
has the key
as its respective integer value and the value
as its count value.The characteristics of Swift's Dictionary
type are inconsistent when outputting normally, so you have to work hard to output them in order.
Even elements that never appear seem to want to print "0 times", so they loop between min()
and max()
.
// Output sequentially
for i in arr.min()!...arr.max()!{
print("\(i):\(numToCount [i, default:0]) times")
}
You use !
like min()!
, max()!
, so if arr
is an empty array, it crashes.I use it intentionally here, but I'm confident that I'm not 100% absolutely nil
in the actual app.Don't use !
unless you intend to crash and let me know if you're wrong
Dictionary
also has sorting methods, so let's make them work.The argument passed to the comparison closure is key-value pair, so it must be arranged in descending order of the value representing the count value.
// In order of the highest number of duplicates
letrank=numToCount.sorted {(-$0.value,$0.key)<(-$1.value,$1.key)}.map {$0.key}
print(rank)
The comparison closure uses a slightly irregular writing style.Usually, if you want to list them in descending order of value, you can write {$0.value>$1.value}
.However, if that is the case, the equalization value will be output out of order, so we are comparing the tuple.I don't think this is being used very well, so I feel like I'm using it too much.
(A1,B1)<(A2,B2)
is the same as B1<B2
when the first element is tiedA1==A2.
Since you want to use the count value as the basis for sorting, sort the value
in ascending order of the original value if it is equal.As for the count value, it's in descending order, so it's quite a half-hearted thing to add -
only to that value.
The last .map{$0.key}
takes only the key
(original integer value) from the key-value pair array.
If you give the arr
as the example in your question, you'll get this output.
[2:2, 0:3, 3:1, 4:2]
0—Three times
1:0 times
2—Two times
3: Once
4: Twice
[0, 2, 4, 3]
The first line may not have been necessary.
Swift's Collection
type has many useful methods.(There are some in other language libraries, and there are others that Swift doesn't.) If you're not used to it, you might understand how it works, but please make good use of it.
The answer is only for the second half, but if you duplicate the function of this answer and return Dictionary
along the way, you can also get Dictionary
for the number of times for each element.
I think there is a more elegant way to do this, but it is written in a rather redundant way to follow the details and make it easier to modify it.
//Original data
let original: Array = [0,0,0,2,2,3,4,4]
// function definition
func sortByCount (ofArray array: Array <Int>) - > Array <Int> {
variableForCount —Dictionary<Int, Int>=Dictionary()
for item:Int in array {
iflet count: Int=dictForCount [item] {
dictForCount [item] = count+1
} else{
dictForCount [item] = 1
}
}// end foreach print (dictForCount)
let result=(dictForCount.sorted {
if($0.value==$1.value){
return $0.key<$1.key
} else{
return $0.value>$1.value
}// end if value is same
}) // end sort close
var resultArray —Array<Int>=Array()
US>for item in result {
resultArray.append(item.key)
}// end foreach append key of dictionary
return resultArray
}
// application result
let orderOfCount —Array<Int>=sortByCount (ofArray:original)
print(orderOfCount)//=> [0,4,2,3]
I think it's possible like this.
© 2024 OneMinuteCode. All rights reserved.