Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get last value inserted into a Set

The MDN documentation for Set says that JavaScript Set objects retain insertion order of elements:

Set objects are collections of values, you can iterate its elements in insertion order.

Is there a way to get the last item inserted into a Set object?

var s = new Set();
s.add("Alpha");
s.add("Zeta");
s.add("Beta");

console.log(getLastItem(s)); // prints "Beta"

Edit

It is possible to implement a Linked Set datastructure container class that has the same interface as Set and has the desired capability. See my answer below.

like image 503
Tamas Hegedus Avatar asked Jan 04 '16 01:01

Tamas Hegedus


3 Answers

I was not able to find any method to get last value inserted in set from ECMA 2015 Specification, may be they never intended such a method, but you can do something like:

const a = new Set([1, 2, 3]);
a.add(10);
const lastValue = Array.from(a).pop();

Edit:

on second thought, a space efficient solution might be:

function getLastValue(set){
  let value;
  for(value of set);
  return value;
}

const a = new Set([1, 2, 3]);
a.add(10);
console.log('last value: ', getLastValue(a));
like image 101
mido Avatar answered Nov 17 '22 10:11

mido


Some ideas:

  • Consider using an array instead of a set. Extracting the last element of an array is easy, e.g.

    array[array.length-1];
    array.slice(-1)[0];
    array.pop(); // <-- This alters the array
    

    If you really need a set, you can convert it to an array when you want to extract the last item, but that will cost time and space.

  • Iterate the set manually. This will cost time but not as much space as copying into an array. For example (there are probably more elegant ways to do this)

    var set = new Set([1, 2, 3]);
    var iter = set.values(), prev, curr;
    do {
      prev = curr;
      curr = iter.next();
    } while(!curr.done)
    var last = prev.value; // 3
    
  • Consider inserting the items in reverse order. Then you only need to get the first item in the set, and that's easier:

    set.values().next().value;
    
  • Subclass Set to add this new functionality:

    class MySet extends Set {
      add(value) {
        super.add(value);
        this.last = value;
      }
    }
    var set = new MySet();
    set.add(1); set.add(2); set.add(3);
    set.last; // 3
    

    Note this will only detect values added with add. To be more complete, it should also detect the latest value when the set is constructed, and update the value when the last item is removed.

like image 41
Oriol Avatar answered Nov 17 '22 12:11

Oriol


Yes, there is a way to do that, you can simply convert the set to an array and pop of the last item

function getLastItem(_set) {
    return [..._set].pop();
}

to get keys/values etc, you can do

return [..._set.entries()].pop(); // the entire entry
return [..._set.keys()].pop();    // the key only
return [..._set.values()].pop();  // the value only

If you don't want to create an array, you'd probably have to iterate and get the last value, like this

var last; s.forEach(k => { last = k }); // last === "Beta"

FIDDLE

like image 14
adeneo Avatar answered Nov 17 '22 12:11

adeneo