I have this as a struct and the populated values would be an array of array
My Goal is just to determine if the hrInt Array of Array is actually empty / populated or Partially populated
How can I simplify this using flatMap or compactMap?
This works,
print(intervalsWodArray.flatMap({$0.hrInt}).flatMap{$0}.flatMap{$0}.isEmpty)
but upon compiling, Xcode is complaining about it being deprecated ('flatMap' is deprecated: Please use compactMap(_:) for the case where closure returns an optional value) and asking me to use compactMap which does not return the desired result when the nested array is actually empty(eg: [[],[],[]])
Don't want to be doing this -
for i in 0..< intervalsWodArray.count {
if let hrInt = intervalsWodArray[i].hrInt {
for x in hrInt {
print("\(x) \(x.isEmpty)")
}
}
}
which results in
[1,1] false
[] true
[] true
This is the playground sample example:
struct intervalsData : Codable {
var intervals : [[Double]]
var hrInt: [[Double]]?
}
var aaa = [intervalsData]()
var bbb = [intervalsData]()
var ccc = [intervalsData]()
aaa.append(intervalsData(intervals: [[0,0],[10,10]],hrInt: [[],[],[]]))
bbb.append(intervalsData(intervals: [[0,0],[10,10]],hrInt: [[1,1],[],[]]))
ccc.append(intervalsData(intervals: [[0,0],[10,10]],hrInt: [[1,1],[2,2],[3,3]]))
print(aaa)
print(bbb)
print(ccc)
// using flatmap returns the desired output
let xxx = aaa.flatMap{$0.hrInt}.flatMap{$0}.flatMap{$0}
let yyy = bbb.flatMap{$0.hrInt}.flatMap{$0}.flatMap{$0}
let zzz = ccc.flatMap{$0.hrInt}.flatMap{$0}.flatMap{$0}
print("---Flatmap returns the Desired Output but is deprecated")
print(xxx, xxx.isEmpty)
print(yyy, yyy.isEmpty)
print(zzz, zzz.isEmpty)
// using compactMap **Does Not** returns the desired output
let a = aaa.compactMap{$0.hrInt}.compactMap{$0}.compactMap{$0}
let b = bbb.compactMap{$0.hrInt}.compactMap{$0}.compactMap{$0}
let c = ccc.compactMap{$0.hrInt}.compactMap{$0}.compactMap{$0}
print("---comactMap returns a different output then flatmap which is not desired")
print(a, a.isEmpty)
print(b, b.isEmpty)
print(c, c.isEmpty)
Output
[__lldb_expr_1254.intervalsData(intervals: [[0.0, 0.0], [10.0, 10.0]], hrInt: Optional([[], [], []]))]
[__lldb_expr_1254.intervalsData(intervals: [[0.0, 0.0], [10.0, 10.0]], hrInt: Optional([[1.0, 1.0], [], []]))]
[__lldb_expr_1254.intervalsData(intervals: [[0.0, 0.0], [10.0, 10.0]], hrInt: Optional([[1.0, 1.0], [2.0, 2.0], [3.0, 3.0]]))]
---Flatmap returns the Desired Output but is deprecated
[] true
[1.0, 1.0] false
[1.0, 1.0, 2.0, 2.0, 3.0, 3.0] false
---comactMap returns a different output then flatmap which is not desired
[[[], [], []]] false
[[[1.0, 1.0], [], []]] false
[[[1.0, 1.0], [2.0, 2.0], [3.0, 3.0]]] false
CodePudding user response:
It looks to me like you're looking for this.
extension IntervalsData {
var hrIntIsAtLeastPartiallyPopulated: Bool {
hrInt?.contains { !$0.isEmpty } ?? false
}
}
CodePudding user response:
let a = [[],[],[]] // - case1 (entirely empty)
let b = [[0,0],[],[]] // - case2 (Partially populated)
let c = [[0,0],[1,1],[2,2]] // - case2 (entirely populated)
Something is entirely empty if all the things are empty, although you also need to say what to do about an empty list - is that entirely empty too?
let aIsEntirelyEmpty = a.allSatisfy(\.isEmpty) // true
Something is partly populated if there is at least one thing where it is empty, and one where it is not
let bIsPartlyPopulated = b.contains(where: { !$0.isEmpty }) && b.contains(where: \.isEmpty) // true
let cIsFullyPopulated = c.allSatisfy { !$0.isEmpty } // true
You need to say what to do about empty lists - should they be considered all empty (nothing is there) or all populated (because nothing is missing)?