Home > OS >  flatMap an (optional) Nested Array within a Struct is deprecated. CompactMap doesn't return des
flatMap an (optional) Nested Array within a Struct is deprecated. CompactMap doesn't return des

Time:04-07

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)?

  • Related