I need to store an array of Int array for ordered duplicates (which are in a Array).
Example:
mainArray = [7, 7, 3, 2, 2, 2, 1,
This is a programming logic problem problem. Your current code is totally wrong.
Here's one way you could solve it:
Start out by sorting your starting array. call that inputArray.
Create new, empty output "outerArray" and "innerArray" variables. Then loop through the entries in inputArray, testing for changes in value. If the value is the same as the last value, add that value to "innerArray". If the value has changed, save the previous innerArray to the outerArray and create a new, empty array and save it to innerArray.
Here's the most boring iterative answer I can imagine. On the other hand it's easy to understand and doesn't suffer from potential complexity problems like reduce
based solutions allegedly do:
var result: [[Int]] = []
var inner: [Int] = []
for i in mainArray {
if i == inner.last {
inner.append(i)
} else {
result.append(inner)
inner = [i]
}
}
result.append(inner)
// result == [[7, 7], [3], [2, 2, 2], [1], [7], [5, 5]]
Another approach extending collections where elements are equatable
extension Collection where Element: Equatable {
var grouped: [[Element]] {
var result: [[Element]] = []
for element in self {
if element == result.last?.last {
result[result.index(before: result.endIndex)].append(element)
} else {
result.append([element])
}
}
return result
}
}
let array = [7, 7, 3, 2, 2, 2, 1, 7, 5, 5]
array.grouped // [[7, 7], [3], [2, 2, 2], [1], [7], [5, 5]]
You can use the forEach
and keep the value of the last element to keep adding to your array while it's not different like in this way:
let mainArray = [7, 7, 3, 2, 2, 2, 1, 7, 5, 5]
func filterTo2DArray(list: [Int] ) -> [[Int]] {
var resultList = [[Int]]()
list.forEach { x -> () in
if let lastValue = resultList.last?.last where lastValue == x {
resultList[resultList.count - 1].append(x)
}
else{
resultList.append([x])
}
}
return resultList
}
let t = filterTo2DArray(mainArray) //[[7, 7], [3], [2, 2, 2], [1], [7], [5, 5]]
I hope this help you.
You can use the reduce
method.
let result = numbers.reduce([[Int]]()) { (var result, num) -> [[Int]] in
if var lastSequence = result.last where lastSequence.first == num {
result[result.count-1].append(num)
} else {
result.append([num])
}
return result
}
reduce
does apply the logic in the closure to an empty 2D array of integers ([[Int]]
) and the first elm of numbers
.
Then it is applied again to the result of the previous iteration and the second array of integers... and so on.
The if
does check whether the number in the last array added to the result is equals to the integer currently examined. If so that integer is added to that array.
Otherwise a new array containing only the new integer is added to the result.
[[7, 7], [3], [2, 2, 2], [1], [7], [5, 5]]
The following code will give you what you need...
let mainArray = [7, 7, 3, 2, 2, 2, 1, 7, 5, 5]
var newArray: [[Int]] = []
for var i=0; i < mainArray.count; i++ {
let element = mainArray[i]
if mainArray.indexOf(element) == i {
var subArray = mainArray.filter({ $0 == element })
newArray.append(subArray)
}
}
print(newArray) // -> [[7, 7, 7], [3], [2, 2, 2], [1], [5, 5]]