DBSCAN c++ implementation For work I had to implement the DBSCAN algorithm in the 3D space for clusters finding. It works, now I wonder how is the quality of the code. I'm especially concerned about incrementing the size of the vector during the for loop in the expandCluster lambda. I followed the Wikipedia article 

struct ivec3
{
    int x;
    int y;
    int z;
};

std::vector&lt;std::vector&lt;ivec3&gt;&gt; dbscan3D(std::vector&lt;ivec3&gt; &amp;dataset, int eps, int min_pts)
{
    // https://en.wikipedia.org/wiki/DBSCAN

    std::vector&lt;std::vector&lt;ivec3&gt;&gt; clusters;
    int idx_current_cluster = 0;

    struct info_point
    {
        ivec3 position;
        int cluster;
    };

    std::unordered_map&lt;int, info_point&gt; map_info_dataset;

    auto getKey = [](ivec3 P)
    {
        return ((int64_t)P.z &lt;&lt; 42) + ((int64_t)P.y &lt;&lt; 21) + (int64_t)P.x;
    };

    for (auto&amp;&amp; P : dataset)
    {
        map_info_dataset[getKey(P)] = info_point{ P, -1 };
    }

    auto regionQuery = [&amp;eps, &amp;map_info_dataset, &amp;getKey](const int key)
    {
        const auto&amp; pos_P = map_info_dataset.at(key).position;

        std::vector&lt;int&gt; keys_neighborPts;

        for (int x = pos_P.x - eps; x &lt;= pos_P.x + eps; ++x)
        {
            for (int y = pos_P.y - eps; y &lt;= pos_P.y + eps; ++y)
            {
                for (int z = pos_P.z - eps; z &lt;= pos_P.z + eps; ++z)
                {
                    int key = getKey({ x, y, z });

                    if (map_info_dataset.count(key))
                    {
                        keys_neighborPts.push_back(key);
                    }
                }
            }
        }
        return keys_neighborPts;
    };

    auto expandCluster = [&amp;eps, &amp;min_pts, &amp;map_info_dataset, &amp;clusters, &amp;regionQuery]
    (const int key, std::vector&lt;int&gt; &amp;keys_neighborPts, int idx_current_cluster)
    {
        clusters.at(idx_current_cluster).push_back(map_info_dataset.at(key).position);
        map_info_dataset.at(key).cluster = idx_current_cluster;

        for (int i = 0; i &lt; keys_neighborPts.size(); ++i)
        {
            auto &amp;local_key = keys_neighborPts[i];
            auto &amp;local_point = map_info_dataset.at(local_key);

            if (local_point.cluster == -1)
            {
                auto keys_neighborPts_local_point = regionQuery(local_key);

                if (keys_neighborPts_local_point.size() &gt;= min_pts)
                {
                    keys_neighborPts.insert(keys_neighborPts.end(), keys_neighborPts_local_point.begin(), keys_neighborPts_local_point.end());
                }

                clusters.at(idx_current_cluster).push_back(local_point.position);
                local_point.cluster = idx_current_cluster;
            }
        }
    };

    for (auto&amp;&amp; P : map_info_dataset)
    {
        const int&amp; key_P = P.first;
        info_point&amp; info_P = P.second;

        if (info_P.cluster != -1)
        {
            continue;
        }

        auto keys_neighborPts = regionQuery(key_P);

        if (keys_neighborPts.size() &gt;= min_pts)
        {
            clusters.emplace_back();
            expandCluster(key_P, keys_neighborPts, idx_current_cluster);
            ++idx_current_cluster;
        }
    }

    return clusters;
}
What is generally less efficient is iterating over an unordered set. This is because the set is actually a hash table of the keys. So whenever you want to iterate over the key-value pairs, a std::map is generally better. 

Also what i apparent is that there is one function to do everything. This makes the code rather hard to follow and oversee. You should rather create one function for every functionality you want to implement and build your algorithm from short but clear functions. In your case there are at least 4 natural subfunctions that occur on the first glance.