Exploring connections among Array Objects on a Map

Here are some JSON examples of Pokemon Battles:

 [
    {
        "battleID": "1",
        "trainers": [
            {
                "LastName": "Ketchum",
                "ForeName": "Ash"
      },
            {
                "LastName": "Mason",
                "ForeName": "Misty"
      }
    ]
  },
    {
        "battleID": "2",
        "trainers": [
            {
                "LastName": "Mason",
                "ForeName": "Misty"
      },
            {
                "LastName": "Brock",
                "ForeName": "Stuart"
      },
            {
                "LastName": "Ian",
                "ForeName": "Foster"
      }
    ]
  },
    {
        "battleID": "3",
        "trainers": [
            {
                "LastName": "Brock",
                "ForeName": "Stuart"
      },
            {
                "LastName": "Ketchum",
                "ForeName": "Ash"
      }
    ]
  }
]

Now, I aim to create a grid that counts the matches between different Pokemon trainers/players. Each match can have up to 4 players at once.

            Ash Ketchum     Misty Mason     Brock Stuart        Ian Foster
Ash Ketchum      2               1               1                  0

Misty Mason      1               2               1                  1

Brock Stuart     1               1               2                  1

Ian Foster       0               1               1                  1

Below is my code snippet:

class Trainer {
constructor(firstname, lastname) {
    this.firstname = firstname;
    this.lastname = lastname;
}

coBattles(trainer) {
    var battles = 0;
    jsonData.map(x => {
        x.trainers.map(y => {
            if (this.firstname === y.ForeName && this.lastname === y.LastName) {
                x.trainers.map(z => {
                    if (trainer.firstname === z.ForeName && trainer.lastname === z.LastName)
                        battles++;
                });
            }
        });
    });
    return battles;
}

}

var pokemonTrainers = [];

// Currently Undesirable as I want a 'unique' array of all participating trainers. 
jsonData.forEach(x => {
    x.trainers.forEach(y => {
        var trainer = new Trainer(y.ForeName, y.LastName);
        pokemonTrainers.push(trainer);
    });
});

//Battles between Misty Mason and Brock Stuart
console.log(pokemonTrainers[1].coBattles(pokemonTrainers[3]));
//returns 1

I am seeking advice on optimizing this code in vanilla JS or with third-party libraries to efficiently handle large amounts of battle data (millions).

Answer №1

If you start by collecting the unique player names, then create an object for each player with a sub-object containing the names of all players, including themselves, you can easily loop through your data to increment the values in that object and ultimately generate a table.

var data =  [{"battleID":"1","trainers":[{"LastName":"Ketchum","ForeName":"Ash"},{"LastName":"Mason","ForeName":"Misty"}]},{"battleID":"2","trainers":[{"LastName":"Mason","ForeName":"Misty"},{"LastName":"Brock","ForeName":"Stuart"},{"LastName":"Ian","ForeName":"Foster"}]},{"battleID":"3","trainers":[{"LastName":"Brock","ForeName":"Stuart"},{"LastName":"Ketchum","ForeName":"Ash"}]}]

var players = {}
var result = {}

// Get all names
data.forEach(function(element) {
  element.trainers.forEach(function(player) {
    players[player.LastName + ' ' + player.ForeName] = 1
  })
})

// Add to result object
Object.keys(players).forEach(function(name) {
  Object.keys(players).forEach(function(element) {
    result[name] = Object.assign(result[name] || {}, {[element]: 0})
  })
})

// Increment values
data.forEach(function(record) {
  record.trainers.forEach(function(trainerA, j) {
    record.trainers.forEach(function(trainerB, i) {
      result[trainerA.LastName + ' ' + trainerA.ForeName][trainerB.LastName + ' ' + trainerB.ForeName]++
    })
  })
})

var table = document.body.querySelector('table');
var thead = '<tr><td></td><td>' + Object.keys(result).join('</td><td>') + '</td></tr>';
table.innerHTML += thead

for (var key in result) {
  var cells = '';
  for (var element in result[key]) {
    cells += '<td>' + result[key][element] + '</td>';
  }

  var row = '<tr><td>' + key + cells + '</td></tr>';
  table.innerHTML += row;
}
td:not(:first-child) {
  text-align: center;
}
<table></table>

Answer №2

Utilizing a 2D map structure for this task can be achieved in the following manner; The provided code snippet will generate a map where each key (player's name) contains another map with the names and number of matches played against competitors.

function getPlayedMatches(players){
  return players.reduce(function(res, battle){
                    var namesList = battle.trainers.map(trainer => trainer.ForeName + " " + trainer.LastName);
                    return namesList.reduce((map, name) => map.has(name) ? map.set(name, namesList.reduce((subMap, playerName) => subMap.has(playerName) ? subMap.set(playerName,subMap.get(playerName)+1)
                                                                                                                    : subMap.set(playerName,1), map.get(name)))
                                                                         : map.set(name,new Map(namesList.map(nom => [nom,1]))), res);
                  }, new Map);
}

var matchData = [{"battleID":"1","trainers":[{"LastName":"Ketchum","ForeName":"Ash"},{"LastName":"Mason","ForeName":"Misty"}]},{"battleID":"2","trainers":[{"LastName":"Mason","ForeName":"Misty"},{"LastName":"Brock","ForeName":"Stuart"},{"LastName":"Ian","ForeName":"Foster"}]},
{"battleID":"3","trainers":[{"LastName":"Brock","ForeName":"Stuart"},{"LastName":"Ketchum","ForeName":"Ash"}]}],
     results = getPlayedMatches(matchData);
console.log(function convertMapToArray(inputMap){
                       return inputMap.constructor === Map ? [...inputMap].map(([val,key]) => [convertMapToArray(val),convertMapToArray(key)])
                                                    : inputMap;
              }(results));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

If a span element is present, apply a specific class to the corresponding

I am working with a dynamic list of links retrieved through AJAX. After parsing the links and appending them to a div, I have encountered an issue where some 'a' elements are followed by a 'span' that needs to be considered. Here is th ...

What is the process for dynamically altering the source file of VueRouter?

Hello, I am working on a project that involves multiple roles using VueJs and Laravel. Laravel is used as the back-end while Vuejs serves as the front-end. The project has three different roles: User, Modirator, and Editor. Here is a snippet of my code ...

Timepicker Bootstrapping

I've been searching for a time picker widget that works well with Bootstrap styling. The jdewit widget has a great style, but unfortunately it comes with a lot of bugs. I'm on a tight deadline for my project and don't have the time to deal w ...

How can I correctly parse nested JSON stored as a string within a property using JSON.parse()?

I am having trouble decoding the response from aws secretsmanager The data I received appears as follows: { "ARN": "arn:aws:secretsmanager:us-west-2:0000:secret:token-0000", "Name": "token", "VersionId&qu ...

Change the right border style for the second and third ToggleButtons in the ToggleButtonGroup

I've been working on this for a few hours now and I can't seem to get it right. Currently, I'm using Mui v5 and trying to style the ToggleButtons to look like regular MUI buttons. So far, I was able to achieve this transformation: https:/ ...

What is the process for browserifying the net.Socket module in Node.js?

I'm exploring ways to connect and query my MS SQL database from JavaScript in a web browser (specifically Chrome, not IE as I don't want to use ActiveX controls). I came across this Node library called Tedious and Browserify to help with this tas ...

Which internal function is triggered in JavaScript when I retrieve the value of an array element by its index?

Check out this fascinating wtfjs code snippet: var a = [,]; alert(a.indexOf(a[0])); This example highlights the difference between uninitialized and undefined values: The array a contains only one uninitialized element. Accessing a[0] returns undefined ...

Adjusting webpage zoom based on different screen sizes

Hey there, I ran into an issue with my web page design. It looks great on my desktop monitors, but when I checked it on my laptop, things went haywire. Strangely, adjusting the zoom to 67% seemed to fix the problem. Both screens have a resolution of 1920 ...

What could be the culprit behind the error in the "blend-mode" function when using .mp4 files in Firefox?

Attempting to utilize mix-blend-mode with an mp4 playing in the background has been a fun experiment. The concept is to have a div containing some text, with the video playing in the background to create an effect on the letters. This method works flawless ...

Save the webpage source code to a file using JavaScript and Grunt

I am facing an issue and need assistance with my project. I have developed an app using GruntJs and now I need to download the source code of a webpage using GruntJs. For instance, let's assume I have a webpage at: example.com/index.html. What I wou ...

What is the most effective way to eliminate asynchronicity in a function?

Imagine having this block of code: const myFunction = async => { const result = await foobar() } const foobar = async () => { const result = {} result.foo = await foo() result.bar = await bar() return result } Now, let's transform i ...

Angular.js: automatically select default option based on ID

In my angular.js single page application, I am retrieving initial data from a rest endpoint. The data consists of a list of IDs representing saved models and a tree of options for cascading dropdowns. How can I automatically set the default path in the t ...

Is it possible to insert a character before a particular word, while also replacing a character in the middle of that word using the .replace method in JavaScript?

I have a script that is able to replace special characters with other characters, but I am looking to enhance it by adding an additional character before the word. For instance, Let's say I start with the word: "zài" and currently change it to: "zai ...

Ways to extract an object from JSON into PHP

Can someone help me figure out how to extract an image link from this API ()? The API endpoint is https://en.wikipedia.org/w/api.php?action=query&prop=pageimages&format=json&piprop=original&titles=Minecraft&pilicense=any. I've tri ...

Tips for converting each item within an array into its own separate element

I currently have an array of objects that I am utilizing to generate a table in Angular. The table is functioning properly and successfully displays the data. However, I now have a requirement to enable editing for each individual object within the table. ...

The state is well-defined within the "ComponentDidMount" function, however, it appears to be undefined in the

After extracting data from my "ComponentDidMount" function and loading it into my state, I verified the presence of the data by console logging the value successfully. However, when trying to access the state in the same manner within the return statement ...

Determining whether the key values in Redis (using Jedis) adhere to the JSON format

I am currently working on a Java program that iterates over Redis database and verifies the key values. If a valid JSON is found, the plan is to extract it into a separate schema (although this part has not been implemented yet); if it is not valid JSON, t ...

What is the correct way to run javascript on a DOM element when ng-show is triggered?

For those who prefer shorter explanations, there's a TLDR at the end. Otherwise, here's a detailed breakdown. I have a form that consists of multiple inputs organized into different "pages" using ng-show. What I aim to achieve is when ng-show r ...

Using React Hooks to render radio buttons within a map iteration

My code contains a nested map function where I try to retrieve values from radio buttons. However, the issue is that it selects all radio buttons in a row instead of just one. Below is the snippet of my code: <TableHead> <TableRow> ...

When clicking on the material-ui autocomplete feature in a React JS application, a blank page unexpectedly opens

I am encountering a problem where, upon clicking the Autocomplete component imported from material-ui, it displays a blank page. const defaultProps = { options: catalogs, getOptionLabel: (option) => option.catalogsLink, }; <Autocomplet ...