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

使用JavaScript求三个集合的并集并实现页面及维恩图展示问题

三个集合并集计算与维恩图展示解决方案

原代码问题分析

你当前的代码直接对输入框的value调用concat是错误的——输入框返回的是字符串,不是数组,无法直接用数组方法处理。必须先把输入的字符串解析成数组,再计算并集。


1. 修正并集计算逻辑

假设用户输入的集合元素用逗号分隔(比如1,2,3),以下是修复后的计算代码:

function myFunction1() {
    // 封装输入解析函数:把输入字符串转成去空后的数组
    const parseInputSet = (elementId) => {
        return document.getElementById(elementId).value
            .split(',')
            .map(item => item.trim())
            .filter(item => item !== ''); // 过滤空字符串
    };

    // 获取三个集合的数组形式
    const setA = parseInputSet("myseta");
    const setB = parseInputSet("mysetb");
    const setC = parseInputSet("mysetc");

    // 用ES6 Set快速计算并集(自动去重)
    const unionSet = [...new Set([...setA, ...setB, ...setC])];

    // 把结果展示到页面指定区域
    document.getElementById("result").textContent = `并集结果:${unionSet.join(', ')}`;
    document.getElementById("union").textContent = unionSet.join(', ');

    // 渲染维恩图
    renderVennDiagram(setA, setB, setC, unionSet);
}

代码说明

  • parseInputSet:统一处理输入,把逗号分隔的字符串转成干净的数组,去掉空格和空项
  • new Set([...setA, ...setB, ...setC]):合并三个数组后用Set去重,再转回数组,比filter+indexOf效率更高
  • 用textContent替代innerHTML更安全(避免XSS风险)

2. 页面基础结构

确保HTML里有对应的输入、结果展示和维恩图容器:

<!-- 输入区域 -->
<div>
    <input type="text" id="myseta" placeholder="集合A(逗号分隔,如1,2,3)">
    <input type="text" id="mysetb" placeholder="集合B(逗号分隔,如2,3,4)">
    <input type="text" id="mysetc" placeholder="集合C(逗号分隔,如3,4,5)">
    <button onclick="myFunction1()">计算并集</button>
</div>

<!-- 结果展示 -->
<div id="result"></div>
<div id="union"></div>

<!-- 维恩图容器 -->
<div id="venn-container" style="width: 600px; height: 400px; margin-top: 20px;"></div>

3. 原生Canvas实现维恩图渲染

不用第三方库,直接用Canvas绘制三个相交圆,并根据元素所属集合标记位置:

function renderVennDiagram(setA, setB, setC, union) {
    const container = document.getElementById("venn-container");
    container.innerHTML = ''; // 清空旧内容

    // 创建Canvas
    const canvas = document.createElement('canvas');
    canvas.width = container.offsetWidth;
    canvas.height = container.offsetHeight;
    container.appendChild(canvas);
    const ctx = canvas.getContext('2d');

    // 圆的基础参数
    const centerX = canvas.width / 2;
    const centerY = canvas.height / 2;
    const radius = 120;

    // 绘制三个相交的圆(带半透明填充)
    // 集合A(左)
    ctx.beginPath();
    ctx.arc(centerX - radius, centerY, radius, 0, Math.PI * 2);
    ctx.strokeStyle = '#ff4444';
    ctx.fillStyle = 'rgba(255, 68, 68, 0.1)';
    ctx.fill();
    ctx.stroke();

    // 集合B(右)
    ctx.beginPath();
    ctx.arc(centerX + radius, centerY, radius, 0, Math.PI * 2);
    ctx.strokeStyle = '#44aa44';
    ctx.fillStyle = 'rgba(68, 170, 68, 0.1)';
    ctx.fill();
    ctx.stroke();

    // 集合C(下)
    ctx.beginPath();
    ctx.arc(centerX, centerY + radius, radius, 0, Math.PI * 2);
    ctx.strokeStyle = '#4444ff';
    ctx.fillStyle = 'rgba(68, 68, 255, 0.1)';
    ctx.fill();
    ctx.stroke();

    // 绘制元素文本的工具函数
    const drawItem = (text, x, y, color) => {
        ctx.fillStyle = color;
        ctx.font = '14px Arial';
        ctx.textAlign = 'center';
        ctx.fillText(text, x, y);
    };

    // 遍历并集元素,根据所属集合定位
    union.forEach(item => {
        const inA = setA.includes(item);
        const inB = setB.includes(item);
        const inC = setC.includes(item);

        let x, y, color;
        if (inA && inB && inC) {
            // 三集合交集
            x = centerX; y = centerY; color = '#ff8800';
        } else if (inA && inB) {
            // A&B交集
            x = centerX; y = centerY - radius/2; color = '#ff6666';
        } else if (inA && inC) {
            // A&C交集
            x = centerX - radius/2; y = centerY + radius/2; color = '#ff66bb';
        } else if (inB && inC) {
            // B&C交集
            x = centerX + radius/2; y = centerY + radius/2; color = '#66ffbb';
        } else if (inA) {
            // 仅A
            x = centerX - radius - 20; y = centerY; color = '#ff4444';
        } else if (inB) {
            // 仅B
            x = centerX + radius + 20; y = centerY; color = '#44aa44';
        } else if (inC) {
            // 仅C
            x = centerX; y = centerY + radius + 20; color = '#4444ff';
        }

        drawItem(item, x, y, color);
    });
}

维恩图说明

  • 三个圆分别对应集合A(红)、B(绿)、C(蓝)
  • 元素根据所属集合被放在对应区域,颜色区分归属:
    • 橙色:同时属于三个集合
    • 浅红/浅绿/浅紫:属于两个集合的交集
    • 原色:仅属于单个集合

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 03:50:43