Using d3.max to nest arrays within an array

I am encountering a situation where I have an array of arrays structured as shown below.

data = [
  [
    {x: 1, y: 40},
    {x: 2, y: 43},
    {x: 3, y: 12},
    {x: 4, y: 60},
    {x: 5, y: 63},
    {x: 6, y: 23}
 ], [
    {x: 1, y: 12},
    {x: 2, y: 5},
    {x: 3, y: 23},
    {x: 4, y: 18},
    {x: 5, y: 73},
    {x: 6, y: 27}
 ], [
    {x: 1, y: 60},
    {x: 2, y: 49},
    {x: 3, y: 16},
    {x: 4, y: 20},
    {x: 5, y: 92},
    {x: 6, y: 20}
  ] 
];

To determine the maximum value of y within this data set, I can utilize a nested d3.max() function call:

d3.max(data, function(d) {
  return d3.max(d, function(d) {
    return d.y;
  });
});

My current challenge lies in deciphering the functionality of this code snippet. While I understand that the second argument in the d3.max() function specifies an accessor function, I am struggling to comprehend how the double invocation of d3.max() correlates with this accessor function.

In essence, what I am seeking is a step-by-step breakdown of how JavaScript processes this code. Even after attempting to dissect it using the console, I am still unable to grasp its full mechanics.

Answer №1

When it comes to programming, the naming of variables plays a crucial role:

// The primary function loops through the main array,
// representing rows in a data set

d3.max(data, function(row) {

  // On the other hand, the nested function iterates over
  // the sub-array, symbolizing columns within a row. This can also be seen as cells in a table.

  return d3.max(row, function(column) {
    return column.y;
  });

});

To explore further details about the d3.max function, check out its source code here: https://github.com/d3/d3.github.com/blob/8f6ca19c42251ec27031376ba9168f23b9546de4/d3.v3.js#L69

Answer №2

Impressive question! For the sake of some friendly competition, I have crafted an ES6 solution to this issue by creating a new array method called Array.prototype.maxByKey(). Let's dive into how this is achieved using pure JS.

Array.prototype.maxByKey = function(k) {
  var m = this.reduce((m,o,i) => o[k] > m[1] ? [i,o[k]] : m ,[0,Number.MIN_VALUE]);
  return this[m[0]];
};
var data = [
[{x: 1, y: 40},{x: 2, y: 43},{x: 3, y: 12},{x: 4, y: 60},{x: 5, y: 63},{x: 6, y: 23}],
[{x: 1, y: 12},{x: 2, y: 5},{x: 3, y: 23},{x: 4, y: 18},{x: 5, y: 73},{x: 6, y: 27}],
[{x: 1, y: 60},{x: 2, y: 49},{x: 3, y: 16},{x: 4, y: 20},{x: 5, y: 92},{x: 6, y: 20}]
],
maxObj = data.map(a => a.maxByKey("y")).maxByKey("y");
console.log(maxObj);

This code snippet works as follows: we use the reduce method to find the index of the object with the highest value. The initial value for reduce is set as the array [0,Number.MIN_VALUE], where 0 represents the index and Number.MIN_VALUE is the smallest number in JS. During each iteration, o refers to the current object and i is the index. The key k determines the property to compare for maximum value.

The ternary comparison o[k] > m[1] ? [i,o[k]] : m compares the current object's property specified by k to m[1]. If it's greater than m[1], the result becomes [i,o[k]]; otherwise, it remains unchanged. At the end, we end up with

[index of max property, value of that property]
in the array.

As you can see, the implementation is straightforward yet efficient.

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

Once the Ionic platform is prepared, retrieve from the Angular factory

I have created a firebase Auth factory that looks like this: app.factory("Auth", ["$firebaseAuth", "FIREBASE_URL","$ionicPlatform", function($firebaseAuth, FIREBASE_URL, $ionicPlatform) { var auth = {}; $ionicPlatform.ready(function(){ ...

Ensuring Vue.js correctly re-renders an array item

In my vue.js 2 project, I am working with an array that has the following structure: data() { return { ports: [ { id: 1, name: "example", "age": 10, scores: [ {index: 1, value: 100}, {index: 2, value: 200} ]}, { id: 2, ...

Removing an object from the scene using three.js

Is there a way to remove an object from a three.js scene? I am trying to delete a cube when a specific key is pressed, but so far I can only clear the entire scene instead of removing just one cube. ...

Using a JSON object in conjunction with an AJAX call to retrieve an array

Having trouble working with the array returned from an ajax call. The array is encrypted using json and looks like this: while ($found_course = mysql_fetch_assoc($sql)) { $info[] = array( 'code' => $found_course['course_cod ...

Utilizing AngularJS to achieve similar functionality to window.bind()

When trying to set the context of a function and pass it as a callback, I am following this approach: myController.myService.validateToken(param) .then( myController.myService.getToken.bind( myController.myService ) ); myController.myService.getToken ...

What is the best way to ensure that the page reloads every time I access it

Creating a social networking website and working on a post edit page. However, encountering an issue when finishing editing the post and clicking 'SAVE EDIT'. I am using the code window.location='post_info.php?post_id='+postid; with AJA ...

Drop Down Automation with Selenium IDE

Currently in the process of automating a User Acceptance Testing (UAT) for a software project at my company. I've completed all the typical tasks like recording actions and clicking on buttons, but ran into an issue with a drop-down menu. The problem ...

Rubaxa-Sortable encountered an error while attempting to execute the 'matches' function on the 'Element': the selector '>*' is invalid

I have implemented Rubaxa Sortable JavaScript library in my Vue.js project. It works perfectly fine with <ul><li> elements, but when I try to use it with table rows, I encounter this error during drag-and-drop: Sortable.min.js:3 Uncaught DOMEx ...

How to effectively utilize multiple Vue instances in your project?

My inquiry is somewhat linked to a similar question on Stack Overflow, but I am uncertain about the level of discouragement towards the approach discussed in relation to Vue. In my situation, I am working on a project where the DOM is generated entirely b ...

Jquery Deferred failing to activate done or when functions

I'm currently working with 2 ajax calls that I'm connecting using $.when in order to execute certain tasks once they are completed. Below is the code snippet: function ajaxCall(url, targetDiv) { dfd = new $.Deferred(); $.ajax({ ...

Is JavaScript Gallery Acting Up? Possible Layer Glitch!

Seeking assistance with a website issue. I have an index.php file set up with a sideshow script in the head that appears on all pages. Additionally, within the index.php file, there is a portfolio.html page that displays a gallery script when loaded. The p ...

Webpack converts 'import' statements to 'require'

I'm currently in the process of compiling my nodeJS project using webpack. Everything seems to be working correctly after compilation, but I've noticed that the imports are being changed to requires. This causes an error when trying to run index. ...

Calculate the total of JSON objects while eliminating duplicates in an array

Below is an array of objects: const lineItems = [ { "lineNumber": "0", "item": "1496", "itemDesc": "wertyuiasdfghj", "qualityReceiptHold": "N", ...

What could be causing the unexpected distribution results when using Perl's List::Util::shuffle?

My extensive vinyl record collection is meticulously organized by a unique catalog ID string. To randomly select 20 records from this collection, I created a script that shuffles the array of catalog IDs and picks out 20 items. However, I noticed that the ...

Is it possible in Vuetify 2 to align the items within the expansion of a v-data-table with the headers of the main component?

I am currently working on rendering a v-data-table where the expandable section serves as a "panel" title and I want the data inside the expansion to align with the headers set at the root level. Despite my efforts, I have not been able to find a way in th ...

Add another condition to the current JavaScript rule

http://jsfiddle.net/e8B9j/2/ HTML <div class="box" style="width:700px">This is a sentence</div> <div class="box" style="width:600px">This is a sentence</div> <div class="box" style="width:500px">This is a sentence</div> ...

Capture cached images stored in the browser memory without relying on the source attribute of the <img> tag

Imagine you're managing a website, samplewebsite.com and you find that the images on it have been resized to very low quality. When you click on an image, you are directed to a 'view_image' page, for example samplewebsite.com/view?image=u ...

Consolidate code by implementing on selectmenu

I need assistance with handling multiple select menus on a View page Below is a snippet of the code: $(function() { var selectSpeed = $('#speed'), selectTest = $('#test'); selectSpeed.selectmenu(); selectTest.selectmenu() ...

"Once the initial date has been selected, v-Calendar's datepicker allows for setting a

Is there a way to trigger an event for the date range picker of v-calendar after the first date is picked or prevent the inputs from adding the dates until both dates have been selected? Here is the Vue component I have: new Vue({ el: "#app", data( ...

Creating a dynamic directive in AngularJS: Learn how to add or remove it from the DOM based on specific conditions

Suppose I have a customized modal directive that looks like this: return { restrict: 'E', templateUrl: 'modal.html', scope: { modalContent: "&", modalOpen: "&" } } And in the HTML: <ng-modal modal-content="co ...