user3755529
user3755529

Reputation: 1196

Return value based on max/min of another value in the same object

having the following object:

var obj = [
 {'a':1, 'b':'jack'},
 {'a':2, 'b':'mario'},
 {'a':3, 'b':'dan'}
]

What is the most correct way using d3.extent() based on 'a' but returning 'b'.

the following line

d3.extent(obj, function(d) {return d.a})

would result in:

[1,3]

I want instead to result in:

['jack','dan']

Upvotes: 4

Views: 159

Answers (2)

Xavier Guihot
Xavier Guihot

Reputation: 61666

Starting d3-array version 2.3, it's possible to use d3.least and d3.greatest in order to respectively get the least / greatest element of the specified iterable according to the specified field:

d3.least(obj, d => d.a); // { 'a': 1, 'b': 'jack' }

thus providing an easy access to a subfield of the least and greatest elements:

var min = d3.least(obj, d => d.a).b;    // jack
var max = d3.greatest(obj, d => d.a).b; // dan

For example:

var obj = [
  { 'a': 1, 'b': 'jack' },
  { 'a': 2, 'b': 'mario' },
  { 'a': 3, 'b': 'dan' }
];

var min = d3.least(obj, d => d.a).b;
var max = d3.greatest(obj, d => d.a).b;

console.log(min);
console.log(max);
<script src="https://d3js.org/d3-array.v2.min.js"></script>

Upvotes: 0

Gerardo Furtado
Gerardo Furtado

Reputation: 102188

Introduction: This question already had a correct answer (>10k users can see it) deleted by the answerer — probably after receiving a downvote. According to this meta suggestion, I'm copy his answer as a community wiki answer, and adding some information of my own. I also voted to undelete his answer.


You cannot do what you described using d3.extent, but you can easily do it with d3.extent and some plain JavaScript.

However, if you want to stick with D3 methods only, you can use d3.minIndex and d3.maxIndex. It's as simple as:

var myDesiredOutput = [
  obj[d3.minIndex(obj, d => d.a)].b,
  obj[d3.maxIndex(obj, d => d.a)].b
];

Here is the demo:

var obj = [{
    'a': 1,
    'b': 'jack'
  },
  {
    'a': 2,
    'b': 'mario'
  },
  {
    'a': 3,
    'b': 'dan'
  }
];

var myDesiredOutput = [
  obj[d3.minIndex(obj, d => d.a)].b,
  obj[d3.maxIndex(obj, d => d.a)].b
];

console.log(myDesiredOutput)
<script src="https://d3js.org/d3-array.v2.min.js"></script>

Pay attention to the fact that you have to reference the d3-array mini-library...

<script src="https://d3js.org/d3-array.v2.min.js"></script>

...because, at the time of writing, neither d3.minIndex nor d3.maxIndex are part of the default bundle.

Upvotes: 2

Related Questions