Home > other >  Swift: How to match ranged values (NSRange) array with full names Strings array?
Swift: How to match ranged values (NSRange) array with full names Strings array?

Time:09-09

Problem:

I have a comment string like = "@Scott Winburn and @Ben Bloodworth and @Alex Gonzalez and @Jerry Anderson"

I have 2 arrays:

  1. that gets the full names = ["@Scott Winburn", "@Ben Bloodworth", "@Alex Gonzalez", "@Jerry Anderson"] = getMentionContactsFromComment()

  2. that gets the ranged values for each full name = [{0, 14}, {19, 15}, {39, 14}, {58, 15}] = setRangedMentionContactValues()

Desired Output:

// if rangedValue == FullName range { // do something }

I'm trying to match those ranged values (in order, cuz the ranged values and full names match the order) with it's associated full name range:

Note: I have to drop the "@" symbol for each name.

I've also tried putting NSRange(location: rangedMentionValue.location, length: totalMentionName.count)

BUT IT FAILS/ BUT if I print the ranged MentionValue.location and tap on the names it return correctly but prints two values (0) (0) (39) (39) etc.

How to make these values match up from the two arrays?

What I've tried:

     for rangedMentionValue in setRangedMentionContactValues() {
        for mentionName in getMentionContactsFromComment() {
          let newMentionName = mentionName.dropFirst()
          let totalMentionName = String(newMentionName)
        
        if gesture.didTapAttributedTextInLabel(label: parent.label, inRange: rangedMentionValue) {
          if rangedMentionValue == NSRange(location: rangedMentionValue.lowerBound, length: totalMentionName.count) { // contact name range 14
//            print("Tapped \(mentionName) with \(rangedMentionValue)")
          }
        }

If I hard code it it, and take it out of the for loop with mentionNames, WORKS how I want for each unique tap on a name like this (I need it dynamic not hard coded), BUT I need the name also dynamic and not hard coded too like this:

    @objc func tappedOnLabel(_ gesture: UITapGestureRecognizer) {
      
//      for value in getMentionContactsFromComment() {
//        print(value)
//      }
      
      for rangedValue in setRangedMentionContactValues() {
        
        if gesture.didTapAttributedTextInLabel(label: parent.label, inRange: rangedValue) {
            if rangedValue == NSRange(location: 0, length: 14) { // contact name range
              print("Tapped Scott Winburn with \(rangedValue)") = "Tapped Scott Winburn { 0, 14 }"
            }
          }

          if gesture.didTapAttributedTextInLabel(label: parent.label, inRange: rangedValue) {
            if rangedValue == NSRange(location: 19, length: 15) { // contact name range
              print("Tapped Ben BloodWorth with \(rangedValue)") = "Tapped Ben BloodWorth with { 19, 15 }"
            }
          }

          if gesture.didTapAttributedTextInLabel(label: parent.label, inRange: rangedValue) {
            if rangedValue == NSRange(location: 39, length: 14) { // contact name range
              print("Tapped Alex Gonzalez with \(rangedValue)") = "Tapped Alex Gonzalez with { 39, 14 }"
            }
          }
      }

**Part 1 of the problem solved: Tapping the correct ranges for each name and printing.. but Part 2 of how to get the name from that tapped range:**
    @objc func tappedOnLabel(_ gesture: UITapGestureRecognizer) {
      // get contactNames for selected cell
      // for each contactName
      // get contactName range
      // condition to equal a single contactName range
      // if value ==  the contactName range [one of these values of ranges (0, 14) (19, 15) (39, 14) (58, 15)]
      // set the contact name
      // set mentionTapped = true
//      for value in getMentionContactsFromComment() {
//        print(value)
//      }
      
      for rangedValue in setRangedMentionContactValues() {
        
        if gesture.didTapAttributedTextInLabel(label: parent.label, inRange: rangedValue) {
          if rangedValue == NSRange(location: rangedValue.location, length: rangedValue.length) { // contact name range
              print("Tapped correct name with \(rangedValue)")
            }
          }
      }
      
    }

Well, @bewithyou solved it by saying I need to map in a dictionary:

      for (mentionName, mentionRange) in zip(getMentionContactsFromComment(), setRangedMentionContactValues()) {
//        print("\(mentionName) : \(mentionRange)")
        
        if gesture.didTapAttributedTextInLabel(label: parent.label, inRange: mentionRange) {
          if mentionRange == NSRange(location: mentionRange.location, length: mentionName.count) {
            let newMentionName = String(mentionName.dropFirst())
            print(newMentionName)
          }
        }
        
      }

CodePudding user response:

As far as I see, you compare the name after you drop "@" on the first index; then you get the lenght of it; after that compare to the range with contains "@" from the beginning. That's the reason I think you dynamic func not working.

Try to change it like below

for rangedMentionValue in setRangedMentionContactValues() {
    for mentionName in getMentionContactsFromComment() {
        if gesture.didTapAttributedTextInLabel(label: parent.label, inRange: rangedMentionValue) {
            if rangedMentionValue == NSRange(location: rangedMentionValue.lowerBound, length: mentionName.count) {
                let newMentionName = String(mentionName.dropFirst())

                break // break the loop after finding the right
                // you can use return here if you want to exit func immediately too
            }
        }
    }
}

CodePudding user response:

This credit goes to @bewithyou for sure:

  for (mentionName, mentionRange) in zip(getMentionContactsFromComment(), setRangedMentionContactValues()) {

// print("(mentionName) : (mentionRange)")

    if gesture.didTapAttributedTextInLabel(label: parent.label, inRange: mentionRange) {
      if mentionRange == NSRange(location: mentionRange.location, length: mentionName.count) {
        let newMentionName = String(mentionName.dropFirst())
        print(newMentionName)
      }
    }
    
  }
  • Related