根据玩家ID累计玩家积分

时间:2019-08-28 18:03:31

标签: javascript object math

采用以下标记:

require 'rails_helper'

RSpec.describe 'creating an instance', type: :request do
  it 'creates an instance' do
    headers = {
      'CONTENT_TYPE' => 'application/json'
    }

    post '/api/v1/instances', params: {
      instance: {
        instance_id_string: 'abc123',
        public_hostname: '0.0.0.0'
      }
    }, headers: headers

    expect(response.body).to eq('asdf')
  end
end

我想做的是合并每个<div data-player-id="1" data-points="8">Player 1</div> <div data-player-id="1" data-points="8">Player 1</div> <div data-player-id="2" data-points="5">Player 2</div> <div data-player-id="2" data-points="5">Player 2</div> <div data-player-id="3" data-points="6">Player 3</div> 的分数。

所以我的想法是遍历data-player-id并为每个玩家创建一个对象,就像这样:

data-player-id

我遇到的问题是合并所有具有相同const points = []; document.querySelectorAll('[data-player-id]').forEach((element) => { const player = { id: element.getAttribute('data-player-id'), points: element.getAttribute('data-points'), } // Combine all players with the same "id" points.push(player); }); 的对象。

不一定要是对象,如果使用数组更好,我很乐意走这条路。

3 个答案:

答案 0 :(得分:1)

您可以将points变量转换为对象而不是数组,并使用播放器ID作为键。然后,在您的querySelector循环中,检查points对象中是否已经存在玩家ID密钥,在这种情况下,对这些点求和。如果不存在,请将其设置为当前元素的点。

const points = {};

document.querySelectorAll('[data-player-id]').forEach((element) => {
  const playerId = element.getAttribute('data-player-id');
  const playerPoints = parseInt(element.getAttribute('data-points'), 10);

  if (playerId in points) {
    points[playerId] += playerPoints;
  } else {
    points[playerId] = playerPoints;
  }
}

如果您想稍后将其转换为问题的相同数据结构,则可以随后进行转换:

const players = {};
for (const playerId in points) {
  players.push({ id: playerId, points: points[playerId] });
}

答案 1 :(得分:1)

您必须在points数组中查找具有玩家ID的对象,如果找到要添加的点,否则请推送一个新对象:

const pointsArr = [];

document.querySelectorAll('[data-player-id]').forEach((element) => {
  const player = {
    id: element.getAttribute('data-player-id'),
    points: +element.getAttribute('data-points')
  }

  const ndx = pointsArr.findIndex(e => e.id  === player.id);
  
  if(ndx > -1){
    pointsArr[ndx].points += +player.points;
  }
  else{
    pointsArr.push(player);
  }
});


console.log(pointsArr);
<div data-player-id="1" data-points="8">Player 1</div>
<div data-player-id="1" data-points="8">Player 1</div>
<div data-player-id="2" data-points="5">Player 2</div>
<div data-player-id="2" data-points="5">Player 2</div>
<div data-player-id="3" data-points="6">Player 3</div>

答案 2 :(得分:1)

您可以使用reduce为其提供初始值。在这里,我使用了一个对象,以便玩家ID是键,而属性值是点。我还对元素进行了分解,以从数据集中获取id和点值,而不是使用getAttribute

const els = document.querySelectorAll('[data-player-id]');

const points = [...els].reduce((acc, element) => {

  // Destructure the id and points from the dataset of the element
  const { dataset: { playerId, points } } = element;

  // If the id doesn't exist in the object create it
  // and set it to zero
  acc[playerId] = acc[playerId] || 0;

  // Add the new points to the total for that id
  // making sure you convert the string to a number
  acc[playerId] += +points;
  return acc;
}, {});

console.log(points);
<div data-player-id="1" data-points="8">Player 1</div>
<div data-player-id="1" data-points="8">Player 1</div>
<div data-player-id="2" data-points="5">Player 2</div>
<div data-player-id="2" data-points="5">Player 2</div>
<div data-player-id="3" data-points="6">Player 3</div>