How to remove an entry from an ordered dictionary at given index?

I am rewriting this block from C++ to Swift.

Here's the original C++ script by Lukhnos Liu:

inline void
Span::removeNodeOfLengthGreaterThan(size_t length)
{
  if (length > m_maximumLength) {
    return;
  }

  size_t max = 0;
  std::set<size_t> removeSet;
  for (std::map<size_t, Node>::iterator i = m_lengthNodeMap.begin(),
                                        e = m_lengthNodeMap.end();
       i != e; ++i) {
    if ((*i).first > length) {
      removeSet.insert((*i).first);
    } else {
      if ((*i).first > max) {
        max = (*i).first;
      }
    }
  }

  for (std::set<size_t>::iterator i = removeSet.begin(), e = removeSet.end();
       i != e; ++i) {
    m_lengthNodeMap.erase(*i);
  }

  m_maximumLength = max;
}

Here's my Swift recraft:

mutating func removeNodeOfLengthGreaterThan(_ length: Int) {
  if length > mutMaximumLength { return }
  var max = 0
  var removalList: Set<Int> = []
  for map in mutLengthNodeMap {
    if map.0 > length {
      removalList.insert(map.0)
    } else if map.0 > max {
      max = map.0
    }
  }
  for (i, key) in removalList.enumerated() {
    mutLengthNodeMap.removeValue(forKey: key)
  }
  mutMaximumLength = max
}

However, it seems that the mutLengthNodeMap.removeValue is removing the wrong thing.
Since mutLengthNodeMap is an ordered dictionary in Swift (an std::map in Cpp), what should I do to remove an entry from this ordered dictionary at given index?

P.S.: For reference, the repo is here:
Failure from zapping overlapped spans. · Issue #6 · ShikiSuen/Megrez (github.com)

Lukhnos Liu's Cpp files:
McBopomofo/Source/Engine/Gramambular at master · openvanilla/McBopomofo (github.com)

What do you mean by "ordered dictionary in swift"? Normal dictionary is unordered, although in case of this example it should not matter.

Don't see an issue offhand (and i don't understand what it's doing, e.g. the values are not used, only the keys, don't know if this is right or wrong). If you can change/run C++ - add a log printout to see what's getting erased, etc and run your swift code with the exact same input, then compare the two logs (diff) and find the difference, after that it would be more obvious what's going on.

Minor style changes.
    for key in mutLengthNodeMap.keys {
        if key > length {
            removalList.insert(key)
        } else if key > max {
            max = key
        }
    }
    for key in removalList {
        mutLengthNodeMap[key] = nil
    }
2 Likes

Ordered dictionary is offered by Apple as an SPM package:

Closed. Reason: I made a mistake in the build() at the 1_BlockReadingBuffer.swift

It doesn't look your C++ code is using the ordered nature of map in the fragment shown (i.e. it doesn't access or remove elements at index, this removes element by key: m_lengthNodeMap.erase(*i);. The order of dictionary elements might still be needed in other portions of code (not shown), or it is unused at all (just the C++'s default implementation of dictionary is ordered).

1 Like

Thank you for mentioning the unnecessity of the ordered dictionary.
Actually, I did use the ordering feature in 4_Node.swift in isCandidateFixed() but I managed to use an alternative feature instead.