Reputation: 9944
I'm developing a Javascript and d3.js application where I'd like to keep track of unique values in a an uploaded dataset. Using one of the new Javascript Set objects seems appealing, but I can't figure out a good way to extract the max and min values of the set. My code:
var mySet = new Set();
mySet.add(5);
mySet.add(10);
mySet.add(20);
console.log( d3.max(mySet) );
This yields undefined
rather than 20.
I've tried the .elements()
, .values()
and .keys()
Set functions, which pass a SetIterator object to d3.max()
but also return undefined
. Using Array.from
appears to be currently unsupported in Chrome.
Any suggestions? I realize that this may be browser-specific as Set objects get rolled out; I'm developing on Chrome v44. I've also looked at using an object object as a dictionary, but can't figure out a concise way to get max/min to work with that structure either.
Edit: I initially asked this question using a mix of arrays and numbers as set elements. The issue still appears in Chrome when using just elements, as above
Upvotes: 7
Views: 11169
Reputation: 2122
You can use native JavaScript destructuring operator with to find the max value in Set.
const mySet = new Set([5, 10, 20]);
const maxInSet = Math.max(...mySet);
Upvotes: 1
Reputation: 21578
It is worth noting, as 6 years have passed since the question was posted, that as of D3 v6 the original problem no longer persists. From that version onwards (see changelog) the methods of the d3-array module accept iterables. Because a Set
itself is iterable the original code will work just fine:
var mySet = new Set();
mySet.add(5);
mySet.add(10);
mySet.add(20);
console.log(d3.max(mySet)); // prints 20
<script src="https://d3js.org/d3.v7.js"></script>
Upvotes: 1
Reputation: 909
You can find Maximum and Minimum values in one line using apply
const mySet = new Set([1, 2, 9, 7, 8]);
Math.max.apply(this, [...mySet]);
Math.min.apply(this, [...mySet]);
Upvotes: 5
Reputation: 384
For Chrome 45+, this should be able to be done without creating a separate array by using Set.prototype.values()
and Array.from()
like so:
var mySet = new Set([1,2,3,3,2,1]);
var setMax = d3.max(Array.from(mySet.values()));
console.log(setMax);
Should you not want to use d3.max()
, Math.max()
with the spread operator will work as well:
var mySet = new Set([1,2,3,3,2,1]);
var setMax = Math.max(...Array.from(mySet.values()));
console.log(setMax);
Upvotes: 0
Reputation: 3561
d3.max
only takes an array (docs). Right now, you are passing in a set to d3.max
that looks like:
{ [5,10,20], 21 }
When you should pass an array like this
[5,10,20,21]
Here's how you should do it:
var mySet = new Set();
mySet.add(5);
mySet.add(10);
mySet.add(20);
mySet.add(21);
myArray = []
// convert set to array
for (v of mySet) {
myArray.push(v)
}
console.log( d3.max(myArray) );
Upvotes: 2