emunsing
emunsing

Reputation: 9944

Find max/min value in a Javascript set

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

Answers (5)

gekh
gekh

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

altocumulus
altocumulus

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

Lalit Yadav
Lalit Yadav

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

nawendt
nawendt

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

cheniel
cheniel

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

Related Questions