1

Long title! I do apologize.

Expected Outcome: Display uniqued string value in UILabel inside a UIView in a stackView. There may be multiple UIViews in the stackView. The stackView lives inside a tableCell. wow....

The views and cells are custom and I am not allowed to create sections. I have to work with what's in the existing codebase.

Issue I am stuck at trying to get the unique optional string values into the respective UILabels. I have a working extension to get unique items from an array. But I just don't know where to implement it, to get the unique values I need.

Code:

// Sample Model Structs
struct Parent {
    var child: [Child]?
}

struct Child {
    var childValue: String?
}

class TableViewCell {  
    var stackView = UIStackView()
    func configureCellFrom(parent: Parent) {
        /// Other code lives in the func to use the Parent struct.   
        if let child = parent.child {
            if child.count > 1 {
                tableCell.topLabel.text = "Multiple Child Values"
                tableCell.ShowChildViewsButton.isHidden = false
                for value in child {
                    let view = CustomUIView() 
                    view.childValue.text = value.childValue.uniqued()
                    self.stackView.addArrangedSubview(view)
                }      
            }
        }
    }
}   
    

extension Sequence where Element: Hashable {
    func uniqued() -> [Element] {
        var set = Set<Element>()
        return filter { set.insert($0).inserted }
    }
}

Above Problem: Where I placed the uniqued() method, will parse out the individual characters in the string. So I know that it is one level too deep. What's the best way to achieve my required result?

Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
jayskev
  • 23
  • 4

2 Answers2

0

Try this:

for (i, value) in child.enumerated() {
    let view = CustomUIView()
    view.childValue.text = value.childValue.uniqued()[i]
    self.stackView.addArrangedSubview(view)
}
Tad
  • 889
  • 9
  • 23
  • I get the error: Cannot assign value of type 'String.Element?' (aka 'Optional') to type 'String?' – jayskev Jan 26 '22 at 02:38
0

The issue there is that uniqued method uses filter method declared on Sequence which will always return an array of the Sequence.Element in the case of a String an array of characters [Character]. You can simply initialize a new string with the array or characters or improve that method to support strings as well. To make that method support strings you need to extend RangeReplaceableCollection. There is a filter method declared on RangeReplaceableCollection which returns Self therefore if you filter a string it will return another string as I showed in this answer from the same post where you found the uniqued method you've shown in your question:

extension RangeReplaceableCollection where Element: Hashable {
    var orderedSet: Self {
        var set = Set<Element>()
        return filter { set.insert($0).inserted }
    }
}

Usage:

view.childValue.text = value.childValue?.orderedSet
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • Off topic: Should the actual for-loop be in the cellForRowAt? Does it matter? – jayskev Jan 26 '22 at 15:10
  • 1
    no keep your logic out of that method – Leo Dabus Jan 26 '22 at 15:25
  • Omg....what options do I have if even this extension doesn't work? I still get duplicates when I show the views in the tableCell. – jayskev Jan 26 '22 at 23:08
  • @jayskev I don't know what you are trying to do. If you apply this method to a string it will return a string with no duplicated characters. If you need to apply this to an array of strings youyou need to apply it directly to your array of strings, not to the string itself. You need to edit your question, post your input and expected output otherwise I can only guess – Leo Dabus Jan 26 '22 at 23:31
  • I think I found my bug: My UIButton seems to call after and while I am scrolling , I need to reset the buttons selected state in the cell. <-- that creates the duplicate values because I think since the button keeps getting called when he cell is queued, maybe the array is re-populating with duplicate data? – jayskev Jan 27 '22 at 00:01
  • 1
    I don't know beware that cells are reused. Print your array and check its contents – Leo Dabus Jan 27 '22 at 00:17