D 如何删除关联数组中最近访问最少的键?

D 如何删除关联数组中最近访问最少的键?,d,D,我有一个限制为x数量的键的关联数组,并希望删除最近访问最少的键以添加另一个键。我在mintl找到了HashAA,它可以在D1中完成任务,但在D2中我什么也没找到。现在是否有任何东西支持此功能,或者我需要维护第二个阵列来完成此工作?我没有真正的答案,但我认为在几分钟内尝试并实现它会很有趣(可能效率很低,可能有问题): 导入标准stdio; 输入性病性状; 结构MyHash(AA,大小限制) 如果(isAssociativeArray!AA) { 别名KeyType!AA密钥; 别名ValueTyp

我有一个限制为x数量的键的关联数组,并希望删除最近访问最少的键以添加另一个键。我在mintl找到了HashAA,它可以在D1中完成任务,但在D2中我什么也没找到。现在是否有任何东西支持此功能,或者我需要维护第二个阵列来完成此工作?

我没有真正的答案,但我认为在几分钟内尝试并实现它会很有趣(可能效率很低,可能有问题):

导入标准stdio;
输入性病性状;
结构MyHash(AA,大小限制)
如果(isAssociativeArray!AA)
{
别名KeyType!AA密钥;
别名ValueType!AA值;
void opIndexAssign(值、键)
{
如果(hash.length>=限制)
{
密钥leastUsed=leastUsedKey;
散列。删除(已删除);
计数。移除(已移除);
}
散列[键]=值;
}
值opIndex(键)
{
计数[键]+;
返回散列[键];
}
值[键]散列;
别名散列这个;
私人:
@属性键leastUsedKey()
{
关键成果;
size\u t maxCount=size\u t.max;
foreach(key;hash.byKey)
{
if(自动计数=输入计数)
{
如果(*计数<最大计数)
{
maxCount=*计数;
结果=键;
}
}
其他的
{
返回键;
}
}
返回结果;
}
大小[键]计数;
}
//只是为了避免在main()中声明变量
@属性void consume(int key){}
void main()
{
MyHash!(int[int],3)hash;
散列[0]=0;
散列[1]=0;
散列[2]=0;
writeln(散列键);
散列[2]。消费;
散列[5]=0;
writeln(hash.keys);//保留2次,添加5次
hash.clear();
散列[0]=0;
散列[1]=0;
散列[2]=0;
散列[0]。消耗;
散列[1]。消费;
散列[1]。消费;
散列[2]。消费;
散列[2]。消费;
散列[2]。消费;
散列[5]=0;
writeln(散列);//(已删除0)
}

内置AAs将在需要时重新刷新以适应更多元素,大小不固定,也不会跟踪您访问或添加元素的方式,而且由于该语言内置了AAs,替代哈希表实现将相对较少(大多数人都只使用内置AAs)

所以,我非常确定您需要自己做这件事——可能是围绕内置的AA类型创建一个包装器,让包装器跟踪对它的所有访问,以便它知道最近访问了哪个密钥


您可以随时查看一些替代容器实现(IIRC it中确实有一个哈希表,但我怀疑它是否能满足您的需要)。就我个人而言,我从来没有听说过哈希表按照您希望的方式运行,所以我认为您所寻找的至少有点不正常。但它应该足够简单,可以围绕AAs创建一个包装器,按照您想要的方式运行。

删除最近使用最少的添加值是标准缓存行为
import std.stdio;
import std.traits;

struct MyHash(AA, size_t Limit)
    if (isAssociativeArray!AA)
{
    alias KeyType!AA Key;
    alias ValueType!AA Value;

    void opIndexAssign(Value value, Key key)
    {
        if (hash.length >= Limit)
        {
            Key leastUsed = leastUsedKey;
            hash.remove(leastUsed);
            counts.remove(leastUsed);
        }

        hash[key] = value;
    }

    Value opIndex(Key key)
    {
        counts[key]++;
        return hash[key];
    }

    Value[Key] hash;
    alias hash this;

private:

    @property Key leastUsedKey()
    {
        Key result;
        size_t maxCount = size_t.max;

        foreach (key; hash.byKey)
        {
            if (auto count = key in counts)
            {
                if (*count < maxCount)
                {
                    maxCount = *count;
                    result = key;
                }
            }
            else
            {
                return key;
            }
        }

        return result;
    }

    size_t[Key] counts;
}

// just to avoid declaring variables in main()
@property void consume(int key) { }

void main()
{
    MyHash!(int[int], 3) hash;

    hash[0] = 0;
    hash[1] = 0;
    hash[2] = 0;

    writeln(hash.keys);

    hash[2].consume;
    hash[5] = 0;

    writeln(hash.keys); // 2 stays, 5 added

    hash.clear();
    hash[0] = 0;
    hash[1] = 0;
    hash[2] = 0;

    hash[0].consume;
    hash[1].consume;
    hash[1].consume;
    hash[2].consume;
    hash[2].consume;
    hash[2].consume;

    hash[5] = 0;
    writeln(hash);  // (0 removed)
}