code: def proximityGrouping(matchArr, distInfo, distLimit, categoryKey):
      
      #Group fi according to their proximity
      matchArrSize = listvalues(matchArr)[0].size
  
      linkageGroups = {p: [p] for p in range(matchArrSize)}
      posToGroup = {p: p for p in range(matchArrSize)}
      groupCategories = {p: set([s]) for p, s in zip(range(matchArrSize),
                                                    matchArr[categoryKey]
                                                    )
                        }
      for (pos1, pos2), dist in zip(distInfo['posPairs'], distInfo['eucDist']):
          if dist > distLimit:
              break
  
          id1 = posToGroup[pos1]
          id2 = posToGroup[pos2]
          if groupCategories[id1].intersection(groupCategories[id2]):
              continue
  
          linkageGroups[id1].extend(linkageGroups[id2])
          groupCategories[id1].update(groupCategories[id2])
          for _pos in linkageGroups[id2]:
              posToGroup[_pos] = id1
          del linkageGroups[id2]
          del groupCategories[id2]
  
      return linkageGroups
docs: #TODO: docstring. Group according to the distance value provided by
          ``distInfo['eucDist']`` with the limitation that each ... category value
          can occur only once per group.
  
      :param matchArr: #TODO: docstring
      :param distInfo: #TODO: docstring, must be sorted, provide keys "posPairs"
          and "eucDist". As generated by :func:`calcDistMatchArr()`
      :param distLimit: #TODO: docstring
      :param categoryKey: #TODO: docstring
  
      :returns: #TODO: docstring