afewminutesofcode.com

Create a Cricket Points Table in Javascript - Part 4

Cover Image for Create a Cricket Points Table in Javascript - Part 4

In this tutorial we are going to complete the rest of the calculations required for the points table.

Jump To Section

Overview

Click on the following links to read part1, part2 or part3 of the series.

In this tutorial we are going to complete the rest of the calculations required for the points table, including creating a function to calculate overs and Net Run Rate.

Calculate a cricket team stat

We are going to start off here by creating a function that will count a stat for a team, it will have the below arguments.

  • matches - Our matches array
  • teamNum - Whether to filter the home team or away team
  • team - The Team eg IND (in this post we will focus on one team but in future posts we will loop over all teams)
  • stat - This function will be able to be used for runs, overs and played status (fin = 1 means the match has finished)
  • opp - where we can toggle to show the current team or their opponent so we can calculate runs against etc.
  • filterTeam - if this is true we will look for the stat only else we will look for a combination of the stat and the team number to get the correct data.
const cricketTeamStat = ({
  matches,
  teamNum = "t1",
  team,
  stat,
  opp,
  filterTeam = false
})

Here we are creating some constants to determine which team to check for to help us to determine whether we want for example runs scored for or runs scored against.

const oppTeam = getOppTeam(teamNum);
const showTeam = opp === true ? oppTeam : teamNum;
const statName = filterTeam ? `${stat}` : `${showTeam}${stat}`;

We will then filter out matches so we are only getting completed matches for the current team and we will use reduce to count the total.

const statTotal = matches
  .filter(
    (match) =>
      match[teamNum] === team && match["type"] === 1 && match["fin"] === 1
  )
  .reduce((total, match) => {
    const value = stat === "Ov" ? calcOver(match[statName]) : match[statName];
    return total + value;
  }, 0);
return statTotal;

Tests

To help illustrate what we are trying to achieve here see the below test where we run the function twice for India once as t1 and once as t2 and we can see that they have scored 2260 during the group stage of the tournament.

it("cricketTeamStat total Runs", () => {
  expect(
    cricketTeamStat({
      matches,
      teamNum: "t1",
      team: "IND",
      stat: "Ru",
      opp: SHOW_TEAM,
      filterTeam: false,
    }) +
      cricketTeamStat({
        matches,
        teamNum: "t2",
        team: "IND",
        stat: "Ru",
        opp: SHOW_TEAM,
        filterTeam: false,
      })
  ).toBe(2260);
});

Calculate an over

An over in cricket is 6 balls. You may have noticed in the above code a reference to calcOver. This is required because the date returns overs in the format of overs.balls so we need to do a calculation to convert this so that we will be able to convert our net run rate properly.

const splitOver = (over) => (over + "").split(".");
const makeFloat = (str) => parseFloat(str) || 0;

export const calcOver = (overStr) => {
  /*
    calc nrr overs here
    (1): 0.167 (2): 0.333 (3): 0.500 (4): 0.667 (5): 0.833
  */
  const over = Number(splitOver(overStr)[0]);
  const balls = Number(splitOver(overStr)[1]);
  const ballsCalculated = balls > 0 ? (balls / 6).toFixed(3) : balls;
  return over + makeFloat(ballsCalculated);
};

Tests

expect(calcOver("1")).toBe(1);
expect(calcOver("1.0")).toBe(1);
expect(calcOver("1.1")).toBe(1.167);
expect(calcOver("1.2")).toBe(1.333);
expect(calcOver("1.3")).toBe(1.5);
expect(calcOver("1.4")).toBe(1.667);
expect(calcOver("1.5")).toBe(1.833);

Accumulate Team Stats Total

The below function simply combines matches where a team is team1 and teams2 to get there total for the competition.

const cricketTeamTotal = ({
  matches,
  team,
  stat,
  opp,
  filterTeam
}) => {
  return (
    cricketTeamStat({
      matches,
      teamNum: TEAM1,
      team,
      stat,
      opp,
      filterTeam
    }) +
    cricketTeamStat({
      matches,
      teamNum: TEAM2,
      team,
      stat,
      opp,
      filterTeam
    })
  );

Calculating Net Run Rate

To calculate net run rate we use the Net Run Rate formulate which is runs for / overs for - runs against / overs against.

export const calcNRR = ({ runsFor, oversFor, runsAgainst, oversAgainst }) => {
  const forTotal = runsFor / oversFor;
  const againstTotal = runsAgainst / oversAgainst;
  return (forTotal - againstTotal).toFixed(3);
};

Tests

it("calcNRR for IND", () => {
  expect(
    calcNRR({
      runsFor: 2260,
      oversFor: 381.0,
      runsAgainst: 1998,
      oversAgainst: 390.0,
    })
  ).toBe("0.809");
});

Create our data for the cricket points table

We now have created functions to handle all the required aspects of the points table. Below we will make a function to store these in an object for each team.

const cricketPointsTableStats = ({ matches, team, config }) => {
  const runsFor = cricketTeamTotal({
    matches,
    team,
    stat: "Ru",
    opp: SHOW_TEAM,
  });
  const oversFor = cricketTeamTotal({
    matches,
    team,
    stat: "Ov",
    opp: SHOW_TEAM,
  });
  const runsAgainst = cricketTeamTotal({
    matches,
    team,
    stat: "Ru",
    opp: SHOW_OPP,
  });
  const oversAgainst = cricketTeamTotal({
    matches,
    team,
    stat: "Ov",
    opp: SHOW_OPP,
  });
  return {
    team: team,
    played: cricketTeamTotal({
      matches,
      team,
      stat: "fin",
      opp: SHOW_TEAM,
      filterTeam: true,
    }),
    won: cricketTeamTotalCalc({
      config,
      matches,
      team,
      stat: WON,
      SHOW_TEAM,
    }),
    lost: cricketTeamTotalCalc({
      config,
      matches,
      team,
      stat: LOST,
    }),
    noresult: cricketTeamTotal({
      matches,
      team,
      stat: "NR",
      opp: SHOW_TEAM,
    }),
    runsFor: runsFor,
    oversFor: oversFor,
    runsAgainst: runsAgainst,
    oversAgainst: oversAgainst,
    netrr: calcNRR({
      runsFor,
      oversFor,
      runsAgainst,
      oversAgainst,
    }),
    pts: cricketTeamTotalCalc({
      config,
      matches,
      team,
      stat: POINTS,
    }),
  };
};

Tests

The below example shows how our results will look in the object for each team.

const config = { pts4Win: 2, pts4NR: 1 };
const expectedData = {
  lost: 1,
  netrr: "0.809",
  noresult: 1,
  oversAgainst: 390,
  oversFor: 381,
  played: 9,
  pts: 15,
  runsAgainst: 1998,
  runsFor: 2260,
  team: "IND",
  won: 7
};

it("cricketPointsTableStats IND", () => {
  expect(
    cricketPointsTableStats({
      matches,
      team: "IND",
      config
    })
  ).toMatchObject(expectedData);

We now have all the data required to render out our points table. In part 5 of the series we will take the data for each team and render it in our react application.

To follow the code so far head over to codesandbox.

Edit new

You might also like

Cover Image for Check if a string contains a substring in JavaScript

Check if a string contains a substring in JavaScript

Since ES6 you can now use the built in includes method eg string.includes(substring).

Cover Image for Create a Cricket Points Table in Javascript - Part 5

Create a Cricket Points Table in Javascript - Part 5

In this tutorial we are going to build our points table based off our previous work.

Cover Image for Create a Cricket Points Table in Javascript - Part 4

Create a Cricket Points Table in Javascript - Part 4

In this tutorial we are going to complete the rest of the calculations required for the points table.

Cover Image for Create a Cricket Points Table in Javascript - Part 3

Create a Cricket Points Table in Javascript - Part 3

In this tutorial we are going to create functions to calculate the total number of wins, losses, no results and points a team has for the tournament.

Cover Image for Create a Cricket Points Table in Javascript - Part 2

Create a Cricket Points Table in Javascript - Part 2

In this tutorial we are going to create a function to calculate when a team has won, lost or there is no result.

Cover Image for Create a Cricket Points Table in Javascript - Part 1

Create a Cricket Points Table in Javascript - Part 1

In this tutorial we are going to Create a Cricket Points Table in JavaScript.

Cover Image for Create a weather voice assistant in React

Create a weather voice assistant in React

In this tutorial we are going to create a simple React app that will use the speechSynthesis API to speak the current temperature in the city we type in.

Cover Image for Getting to know the many voices in your browser

Getting to know the many voices in your browser

The Speech Synthesis API has been around since about 2014 but still has not gained a huge amount of traction on many sites.

Cover Image for How to create a custom sort order in javascript

How to create a custom sort order in javascript

When sorting an array of objects in JavaScript, usually we will want to sort alphabetically or numerically, but there are also some cases were we might need a custom sort order.

Cover Image for How to sort an array alphabetically in javascript

How to sort an array alphabetically in javascript

To sort an array alphabetically in javascript you can use the sort function.

Cover Image for How to sort an array numerically in javascript

How to sort an array numerically in javascript

To sort an array in javascript use the sort method sort((a, b) => a - b)

Cover Image for How to convert an array into an object in javascript

How to convert an array into an object in javascript

To convert an array into an object we will create a function and give it 2 properties, an array and a key..

Cover Image for How to filter an array in javascript

How to filter an array in javascript

To filter an array in Javascript we can pass in a condition to the built in filter function.