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

如何合并JSON响应多列表相同条目并检测用户双向互投匹配对

问题:检测用户双向投票匹配对

需要处理一个JSON响应,找出所有votedPositive的双向匹配对——即A投票给B,同时B也投票给A的用户ID组合。

给定的JSON结构:

const participants =  {
    "data": [
        {
            "userId": 2,
            "votedPositive": [
                {
                    "userId": 1
                }
            ]
        },
        {
            "userId": 3,
            "votedPositive": [
                {
                    "userId": 5
                }
            ]
        },
        {
            "userId": 4,
            "votedPositive": []
        },
        {
            "userId": 5,
            "votedPositive": [
                {
                    "userId": 2
                },
                {
                    "userId": 3
                }
            ]
        },
        {
            "userId": 6,
            "votedPositive": []
        },
        {
            "userId": 7,
            "votedPositive": []
        },
        {
            "userId": 8,
            "votedPositive": []
        },
        {
            "userId": 9,
            "votedPositive": []
        },
        {
            "userId": 10,
            "votedPositive": []
        },
        {
            "userId": 11,
            "votedPositive": []
        },
        {
            "userId": 12,
            "votedPositive": []
        },
        {
            "userId": 1,
            "votedPositive": [
                {
                    "userId": 2
                }
            ]
        }
    ]
}

预期输出是双向匹配对列表,比如[[1,2], [3,5]]。

已编写的部分代码:

var participantsList = [];
for (var index = 0; index < participants.length; index++) {
    for (var i = 0; i < participants[index]["votedPositive"].length; i++) {
        participantsList.push([participants[index]["userId"], participants[index]["votedPositive"][i]["userId"]])
    }
}

for (var index = 0; index < participantsList.length; index++) {
    participantsList[index].sort(function (a, b) {
        return a - b;
    });
}

当前运行后得到的结果:

[ [ 1, 2 ], [ 3, 5 ], [ 2, 5 ], [ 3, 5 ], [ 1, 2 ] ]

现在的困惑:不确定当前代码是否正确,且不知道如何过滤重复组合,得到最终的双向匹配对列表。


解决方案

先修正原代码的小错误

原代码里participants.length是错误的,因为participants是包含data数组的对象,正确遍历对象应该是participants.data.length,否则会无法获取到用户数据。

高效的双向匹配检测方法

比起先收集所有投票对再去重,更高效的方式是先建立用户投票的映射表,直接检测双向关系,同时避免重复记录:

// 第一步:建立用户ID到其投票对象的映射
const voteMap = new Map();
participants.data.forEach(user => {
    // 提取当前用户投票的所有userId,转为集合方便快速查找
    const votedIds = new Set(user.votedPositive.map(item => item.userId));
    voteMap.set(user.userId, votedIds);
});

// 第二步:找出双向匹配对,同时避免重复添加(比如[1,2]和[2,1]只存一次)
const mutualMatches = new Set();
participants.data.forEach(user => {
    const userId = user.userId;
    user.votedPositive.forEach(voted => {
        const votedId = voted.userId;
        // 只处理userId < votedId的情况,防止重复
        if (userId < votedId) {
            // 检查对方是否也投了当前用户
            if (voteMap.get(votedId)?.has(userId)) {
                mutualMatches.add(`${userId},${votedId}`);
            }
        }
    });
});

// 把集合转为数组格式的最终结果
const result = Array.from(mutualMatches).map(str => str.split(',').map(Number));
console.log(result); // 输出 [[1,2], [3,5]]

基于现有代码的后续处理

如果你想基于已有的participantsList继续处理,可以统计每个排序后数组的出现次数,只保留出现次数≥2的组合:

// 修正原代码的遍历对象
var participantsList = [];
for (var index = 0; index < participants.data.length; index++) {
    for (var i = 0; i < participants.data[index]["votedPositive"].length; i++) {
        participantsList.push([participants.data[index]["userId"], participants.data[index]["votedPositive"][i]["userId"]])
    }
}

// 排序每个投票对
for (var index = 0; index < participantsList.length; index++) {
    participantsList[index].sort(function (a, b) {
        return a - b;
    });
}

// 统计每个组合的出现次数
const countMap = {};
participantsList.forEach(pair => {
    const key = pair.join(',');
    countMap[key] = (countMap[key] || 0) + 1;
});

// 过滤出出现次数≥2的组合,转为数组
const finalResult = Object.keys(countMap)
    .filter(key => countMap[key] >= 2)
    .map(key => key.split(',').map(Number));

console.log(finalResult); // 输出 [[1,2], [3,5]]

两种方法对比

  • 映射表方法:时间复杂度更低,仅需两次遍历,适合数据量大的场景,同时天然避免重复记录。
  • 统计次数方法:逻辑简单,无需大幅改动原有代码,适合小数据量场景。

内容的提问来源于stack exchange,提问作者Marcel Dz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 17:20:30