You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中使用链表处理MySQL查询结果时的无限重复问题及排序实现咨询

Unity中使用链表处理MySQL查询结果时的无限重复问题及排序实现咨询

嘿,我来帮你梳理下这个问题里的两个核心问题——无限重复和排序失效的原因,还有对应的修复方案:

一、无限重复的根源

你代码里的head是PlayerController类的成员变量,每次调用GetResult获取新数据时,都没有重置head为null。这就导致每次拉取到新的玩家数据后,都会把新元素追加到上一次创建的旧链表后面,数据不断累积,看起来就像无限重复了。比如第一次拉3条数据,链表有3个节点;第二次再拉,又加3个,变成6个,以此类推。

二、排序逻辑的问题

现在的链表插入逻辑只处理了两种简单情况(链表为空、只有一个节点),剩下的所有情况都直接把新节点加到链表末尾,完全没有做降序插入的判断,自然实现不了按分数从高到低排序的需求。

三、修正后的代码示例

我把GetResult方法和相关逻辑改了下,你可以参考:

IEnumerator GetResult()
{
    using (WWW www = new WWW(resultURL))
    {
        yield return www;
        byte[] bytesForEncoding = System.Text.Encoding.UTF8.GetBytes(www.text);
        string str = System.Text.Encoding.UTF8.GetString(bytesForEncoding);
        Debug.Log(str);
        ranking = JsonConvert.DeserializeObject<PlayerDataVO[]>(str);
        
        // 关键:每次获取新数据前重置链表头,避免旧数据残留
        head = null;

        for (int i = 0; i < ranking.Length; i++)
        {
            string name = ranking[i].getName();
            string score = ranking[i].getScore();
            PlayerDataVO vo = new PlayerDataVO(name, score);

            // 处理空链表的情况
            if (head == null)
            {
                head = vo;
                continue;
            }

            // 先把字符串分数转成int,方便比较
            if (!int.TryParse(vo.getScore(), out int voScore))
            {
                Debug.LogWarning($"玩家{name}的分数格式不合法,跳过排序");
                continue;
            }
            if (!int.TryParse(head.getScore(), out int headScore))
            {
                Debug.LogWarning($"头部玩家{head.getName()}的分数格式不合法,跳过当前玩家");
                continue;
            }

            // 处理新节点分数比头节点高的情况,直接插在头部
            if (voScore > headScore)
            {
                vo.next = head;
                head = vo;
                continue;
            }

            // 遍历链表,找到合适的插入位置(降序排列)
            PlayerDataVO current = head;
            while (current.next != null)
            {
                if (!int.TryParse(current.next.getScore(), out int currentNextScore))
                {
                    Debug.LogWarning($"玩家{current.next.getName()}的分数格式不合法,跳过比较");
                    current = current.next;
                    continue;
                }
                if (voScore > currentNextScore)
                {
                    // 把vo插在current和current.next之间
                    vo.next = current.next;
                    current.next = vo;
                    break;
                }
                current = current.next;
            }

            // 如果遍历到末尾都没找到比vo分数低的,就把vo加到最后
            if (current.next == null)
            {
                current.next = vo;
            }
        }

        Debug.Log(head.getName());
        Debug.Log("데이터 길이 : " + ranking.Length);
        
        // 打印验证链表
        PlayerDataVO temp2 = head;
        while (temp2 != null)
        {
            print(temp2.getName() + " " + temp2.getScore());
            temp2 = temp2.next;
        }
    }
}

四、额外优化点

其实如果不是必须用链表实现排序,你完全可以直接对ranking数组进行排序,代码会简洁很多,出错概率也更低:

// 直接对数组按分数降序排序
Array.Sort(ranking, (a, b) => 
{
    if (!int.TryParse(a.getScore(), out int scoreA) || !int.TryParse(b.getScore(), out int scoreB))
    {
        return 0;
    }
    return scoreB.CompareTo(scoreA);
});

排序后直接遍历数组就能得到降序的结果,不用手动维护链表的插入逻辑~

备注:内容来源于stack exchange,提问作者gdsafgd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 06:59:49