我正在创建一个配对功能,在那里两个相同体重的球员将被配对.

它目前在相同重量的基础上工作.现在,我增加了另一个条件,球员有自己的水平.我的第一个条件是基于同样的体重.这起作用了.我的第二个条件是关于"班级",如果玩家有相同的班级,他们不应该被匹配/配对.

const source = [
    {
        entryID: 1,
        entryName: "player1",
        weight: 1900,
        class: ['a', 'b'],

    },
    {
        entryID: 2,
        entryName: "player2",
        weight: 1900,
        class: ['a', 'b'],

    },
    {
        entryID: 3,
        entryName: "player3",
        weight: 1900,
        class: ['c', 'd'],

    },
    {
        entryID: 4,
        entryName: "player4",
        weight: 1900,
        class: ['c', 'd'],
    },

];

console.log(combine(source))

function combine(data = [], different = 0, maxGroupSize = 2) {
    const groups = [], related = [], sortedData = [...data].sort((a, b) => a.weight - b.weight),
        alreadyInRela = (setX, eName) => {
            let list = [...setX, eName]
            return related.some(rela => list.every(l => rela.has(l)))
        };
    
    sortedData.forEach((el, indx) => {
        let place = groups.findIndex( // find a place in a group forEach element, use indx as track
            g => g.names.size < maxGroupSize              // is the group incomplete ?
                && !g.names.has(el.entryName)             // is entryName not in the group list (names Set) ?
                && (el.weight - g.weight) <= different
                && !alreadyInRela(g.names, el.entryName) // is (entryName + group list) does not already used ?
        )

        if (place < 0) { // not found -> create new group
            let names = new Set().add(el.entryName)                      // create new group
            groups.push({ names, indxs: [indx], weight: el.weight })  // group constitutive info 
            related.push(names)                                      // keep track of group list
        } else { // find a place in a group
            groups[place].names.add(el.entryName)  // related list is also updated
            groups[place].indxs.push(indx)        // add indx to retreive element in sortedData 
        }
    });

    return groups.reduce((r, g, i) => { // build result
        if (g.indxs.length > 1) {
            let key = `${i}_` + g.indxs.map(x => sortedData[x].weight).join('_')
            r[key] = []
            g.indxs.forEach(x => r[key].push(sortedData[x]))
        }
        return r
    }, {})
}

我目前的输出:

{
    0_1900_1900: [
        {
            class: ["a", "b"],
            entryID: 1,
            entryName: "player1",
            weight: 1900
        },
        {
            class: ["a", "b"],
            entryID: 2,
            entryName: "player2",
            weight: 1900
        }
    ],
    1_1900_1900: [
        {
            class: ["c", "d"],
            entryID: 3,
            entryName: "player3",
            weight: 1900
        },
        {
            class: ["c", "d"],
            entryID: 4,
            entryName: "player4",
            weight: 1900
        }
    ]
}

目标输出(正如我们在这里看到的,具有相同职业的玩家没有连接/组合.这就是我需要瞄准的目标):

{
    0_1900_1900: [
        {
            class: ["a", "b"],
            entryID: 1,
            entryName: "player1",
            weight: 1900
        },
        {
            class: ["c", "d"],
            entryID: 3,
            entryName: "player3",
            weight: 1900
        }
    ],
    1_1900_1900: [
        {
            class: ["a", "b"],
            entryID: 2,
            entryName: "player2",
            weight: 1900
        },
        {
            class: ["c", "d"],
            entryID: 4,
            entryName: "player4",
            weight: 1900
        }
    ]
}

推荐答案

下面的代码存储组中的所有类,并在插入之前比较新玩家的类:

const source = [
    {
        entryID: 1,
        entryName: "player1",
        weight: 1900,
        class: ['a', 'b'],

    },
    {
        entryID: 2,
        entryName: "player2",
        weight: 1900,
        class: ['a', 'b'],

    },
    {
        entryID: 3,
        entryName: "player3",
        weight: 1900,
        class: ['c', 'd'],

    },
    {
        entryID: 4,
        entryName: "player4",
        weight: 1900,
        class: ['c', 'd'],
    },

];

console.log(combine(source))

function combine(data = [], different = 0, maxGroupSize = 2) {
    const groups = [], related = [], sortedData = [...data].sort((a, b) => a.weight - b.weight),
        alreadyInRela = (setX, eName) => {
            let list = [...setX, eName]
            return related.some(rela => list.every(l => rela.has(l)))
        };
    
    sortedData.forEach((el, indx) => {
        let place = groups.findIndex( // find a place in a group forEach element, use indx as track
            g => g.names.size < maxGroupSize              // is the group incomplete ?
                && !g.names.has(el.entryName)             // is entryName not in the group list (names Set) ?
                && (el.weight - g.weight) <= different
                && !alreadyInRela(g.names, el.entryName) // is (entryName + group list) does not already used ?
                && el.class.every(c => !g.usedClasses.has(c)) // check class
        )

        if (place < 0) { // not found -> create new group
            let names = new Set().add(el.entryName)                      // create new group
            groups.push({ names, indxs: [indx], weight: el.weight, usedClasses: new Set(el.class) })  // group constitutive info 
            related.push(names)                                      // keep track of group list
        } else { // find a place in a group
            groups[place].names.add(el.entryName)  // related list is also updated
            el.class.forEach(c => groups[place].usedClasses.add(c)) // add classes
            groups[place].indxs.push(indx)        // add indx to retreive element in sortedData 
        }
    });

    return groups.reduce((r, g, i) => { // build result
        if (g.indxs.length > 1) {
            let key = `${i}_` + g.indxs.map(x => sortedData[x].weight).join('_')
            r[key] = []
            g.indxs.forEach(x => r[key].push(sortedData[x]))
        }
        return r
    }, {})
}

Javascript相关问答推荐

如何才能拥有在jQuery终端中执行命令的链接?

如何在RTK上设置轮询,每24小时

格式值未保存在redux持久切片中

Angular 17—每当一个布尔变量变为真时触发循环轮询,只要它保持为真

WebGL 2.0无符号整数输入变量

html + java script!需要帮助来了解为什么我得到(无效的用户名或密码)

如何将多维数组插入到另一个多维数组中?

覆盖加载器页面避免对页面上的元素进行操作

是否可以将Select()和Sample()与Mongoose结合使用?

无法重定向到Next.js中的动态URL

将范围 Select 器添加到HighChart面积图

在Java脚本中录制视频后看不到曲目

P5JS-绘制不重叠的圆

在JavaScript中,有没有一种方法可以迭代字符串的词法标记?

如何在独立的Angular 应用程序中添加Lucide-Angel?

用Reaction-RT-Chart创建实时条形图

我的NavLink活动类在REACT-ROUTER-V6中出现问题

如何使用Cypress在IFRAME中打字

JavaScript:多个图像错误处理程序

我们是否可以在reactjs中创建多个同名的路由