【问题标题】:How can i combine 2 data in 1 array with different value?如何将 1 个数组中的 2 个数据组合成不同的值?
【发布时间】:2021-12-20 03:45:35
【问题描述】:

目前,我有一个函数,可以在 1 个数组中加入 2 个具有相同权重的数据。我的目标是如何以不同的价值加入他们?我有一个等于 15 的默认值作为差异。 附加:我需要限制。数组中应该只有小于或大于 15 个重量差异。如果超过,那么它不应该在同一个数组中。

例如:

entryID:1 weight:1900 和 entryID:2 1915 将在数组 1 中... entryID:3 weight:1915 和 entryID:4 1920 将在数组 2 中。

//当前sn-p如果权重相同,则将2个数据加入1个数组中。我的目标是将 2 个数据也加入 1 个数组中,但权重不同。

const source = [{
    entryID: 1,
    entryName: 'player1',
    weight: 1900,
    
  },
  {
    entryID: 2,
    entryName: 'player2',
    weight: 1915,
   
  },
  {
    entryID: 3,
    entryName: 'player3',
    weight: 1915,
  
  },
  {
    entryID: 4,
    entryName: 'player4',
    weight: 1920,
  
  },
  {
    entryID: 5,
    entryName: 'player5',
    weight: 1950,
    
  },
  {
    entryID: 6,
    entryName: 'player6',
    weight: 1965,
   
  },




  ]


  const combine = (source) => {
    return source.reduce((acc, curr) => {
      if (acc[curr.weight]) {
        const levelArr = acc[curr.weight];
        const last = levelArr[levelArr.length - 1];
        if (last.length === 2) {
          levelArr.push([curr])
        } else {
          last.push(curr)
        }
      } else {
        acc[curr.weight] = [
          [curr]
        ];
      }
      return acc;
    }, {})
  };


  var result = combine(source)
  var html = ""
  var keys = Object.keys(result) //if there are more than one keys i.e : 2..

  for (var i = 0; i < keys.length; i++) {
  result[keys[i]].forEach(function(val) {

    val.forEach(function(value, index) {

     
        var entryIDs = index == 0 ? "entryIDM[]" : "entryIDW[]"
        var handlers = index == 0 ? "handlerM[]" : "handlerW[]"
        var weights = index == 0 ? "weightM[]" : "weightW[]"
        html += `<input type="text" name="${entryIDs}" value="${value.entryID}"> 
                 <input type="text" name="${handlers}" value="${value.entryName}">
                 <input type="text" name="${weights}" value="${value.weight}">
                 `
    })
    })
    
    
  }
  document.getElementById("result").innerHTML = html 

console.log(result);
<div id="result">
</div>

我的预期输出:

{
  1900_1915: [[{
  entryID: 1,
  entryName: "player1",
  weight: 1900
}, {
  entryID: 2,
  entryName: "player2",
  weight: 1915
{
  1915_1920: [[{
  entryID: 3,
  entryName: "player3",
  weight: 1915
}, {
  entryID: 4,
  entryName: "player4",
  weight: 1920
}

【问题讨论】:

  • 你能将预期的输出添加到问题中吗?
  • 您的要求还不清楚。你的句子“我的目标是在 1 个数组中加入 2 个数据,但权重不同。”不清楚。如果你想加入一个数组,你必须想要一些共同的东西,对吧?您当前的逻辑基于相同的权重是正确的。请添加您的预期输出或详细说明。
  • 这是我的预期输出:{ 1900_1915: [[{ entryID: 1, entryName: "player1", weight: 1900 }, { entryID: 2, entryName: "player2", weight: 1915 { 1915_1920: [[{ entryID: 3, entryName: "player3", weight: 1915 }, { entryID: 4, entryName: "player4", weight: 1920
  • @HardikShah 如果让您感到困惑,我很抱歉。在我目前的功能上。我可以将 2 个数据加入 1 个具有相同权重的数组中。但是对于我的下一个目标。我想加入 2 个不同值的数据。差异不应超过 15。我提供旧代码的原因是因为我认为它接近我的目标。我只需要添加一些功能即可。对不起,我是新手。

标签: javascript html


【解决方案1】:

这是一种方法。您可以调整用于合并数据的difference 值。

const source = [
  { entryID: 1,entryName: 'player1', weight: 1900 },
  { entryID: 2, entryName: 'player2', weight: 1915 },
  { entryID: 3, entryName: 'player3', weight: 1915 },
  { entryID: 4, entryName: 'player4', weight: 1920 },
  { entryID: 5, entryName: 'player5', weight: 1950 },
  { entryID: 6, entryName: 'player6', weight: 1965 },
]

function newCombine(data, difference) {
  let nonMatched = [...data]
  const groups = {}

  for (let i = 0; i < nonMatched.length - 1; i++) {
    const first = nonMatched[i]

    inner: for (let j = nonMatched.length - 1; j > i; j--) {
      const second = nonMatched[j]
      const delta = Math.abs(first.weight - second.weight)

      if (delta <= difference) {
        const groupKey = `${first.weight}_${second.weight}`
        groups[groupKey] = [first, second]
        nonMatched = nonMatched.filter(
          obj => obj.entryID != first.entryID && obj.entryID != second.entryID
        )
        i = -1
        break inner
      }
    }
  }
  return { ...groups, ...nonMatched }
}

const a = newCombine(source, 15)
console.log(a)

编辑:

在上面的 sn-p 中,权重值被用于为分组数据设置一个键。如果有多个具有相同权重值的玩家,这将导致问题。以下输入:

const source = [
  { entryID: 1, entryName: 'player1', weight: 1900 },
  { entryID: 2, entryName: 'player2', weight: 1915 },
  { entryID: 3, entryName: 'player3', weight: 1915 },
  { entryID: 4, entryName: 'player4', weight: 1915 },
  { entryID: 5, entryName: 'player5', weight: 1915 },
]

将输出:

{
  '0': { entryID: 1, entryName: 'player1', weight: 1900 },
  '1915_1915': [
    { entryID: 3, entryName: 'player3', weight: 1915 },
    { entryID: 4, entryName: 'player4', weight: 1915 }
  ]
}

这导致一些条目被删除。所以最好为键使用更唯一的值,例如entryID

const groupKey = `${first.entryID}_${second.entryID}`

编辑 2:

如果不匹配具有相同entryName的玩家,则条件可以更改为:

if (delta <= difference && first.entryName !== second.entryName) { 
...
}

const source = [
  { entryID: 1, entryName: 'player1', weight: 1915 },
  { entryID: 3, entryName: 'player2', weight: 1910 },
  { entryID: 2, entryName: 'player1', weight: 1920 },
  { entryID: 5, entryName: 'player1', weight: 1910 },
  { entryID: 4, entryName: 'player2', weight: 1920 },
  { entryID: 6, entryName: 'player1', weight: 1915 },
]

function newCombine(data, difference) {
  let nonMatched = [...data]
  const groups = {}

  for (let i = 0; i < nonMatched.length - 1; i++) {
    const first = nonMatched[i]

    inner: for (let j = nonMatched.length - 1; j > i; j--) {
      const second = nonMatched[j]
      const delta = Math.abs(first.weight - second.weight)

      if (delta <= difference && first.entryName !== second.entryName) {
        const groupKey = `${first.weight}_${second.weight}`
        groups[groupKey] = [first, second]
        nonMatched = nonMatched.filter(
          obj => obj.entryID != first.entryID && obj.entryID != second.entryID
        )
        i = -1
        break inner
      }
    }
  }
  return { ...groups, ...nonMatched }
}


const a = newCombine(source, 15)
console.log(a)

【讨论】:

  • 哇。这看起来很棒。我明天试试。我希望你能等我。太感谢了。我现在会对此表示赞同。 :D
  • 这非常有效。谢谢。
  • 我还有问题吗?如何避免 1 个数组中的玩家名称重复?不应匹配同名玩家。 prnt.sc/1ym4jup(如果截图坏了,这里是另一个截图snipboard.io/F1DNfQ.jpg
  • @UlquiorraSchiffer 检查difference 值的条件可以更新以检查被比较的两个玩家是否具有相同的entryName。我更新了答案并将条件包含在最后一个 sn-p 中。
  • 完美。太感谢了。救世主。
【解决方案2】:

如果我正确理解您的问题,您希望按重量对它们进行分组。然后你可以在检查列表是否具有相同的权重时使用相同的逻辑。

您不需要检查它们是否具有相同的权重,因为字典会将它们的权重作为键。

const combine = (source) => {
    return source.reduce((acc, curr) => {
      const wList = acc[curr.weight] || [];
      wList.push(curr);
      acc[curr.weight] = wList;

      return acc;
    }, {})
  };

如果您需要输入验证:

const combine = (source) => {
    return source.reduce((acc, curr) => {
      // If not greater or less than 15, means not 15
      if (curr.weight != 15) {
         return acc;
      }

      // values here are valid
      const wList = acc[curr.weight] || [];
      wList.push(curr);
      acc[curr.weight] = wList;

      return acc;
    }, {})
  };

【讨论】:

  • 根据我需要做的,我需要设置一个限制。只有大于或小于等于 15 的权重差异才应该在同一个数组中。如果超过,那么它不应该在同一个数组中。我需要把这个限制放在哪里?谢谢你。赞赏
  • 我不确定我现在明白了。如果您只需要存储该范围内的权重,则在 push 调用之前添加 if 语句。如果你需要限制列表大小,也许你可以先映射,运行reduce的时候再创建一个额外的key。
  • 我明白了。太感谢了。我明天试试。会及时更新。再次感谢你
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-06
  • 2015-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多