0

Title basically, I've just begun exploring es6 Map because of it's unique properties, and I'm a bit concerned about pure operations.

For example often remove properties from objects I work with using this:

function cloneOmit( obj, props ) {
  const keys = !Array.isArray(props)
    ? Object.keys(obj).filter(k => k !== props)
    : Object.keys(obj).filter(k => !props.includes(k));

  return keys.reduce(
    (clone, key) => {
      return { ...clone, [key]: obj[key] };
    },
    {}
  );
}

I rewrote this to work with Maps:

function cloneOmitMap( map, keys ) {
  const oldKeys = Array.from(map.keys());
  const newKeys = !Array.isArray(keys)
    ? oldKeys.filter(k => k !== keys)
    : oldKeys.filter(k => !keys.includes(k));

  return newKeys.reduce((newMap, key) => {
    return newMap.set(key, map.get(key));
  }, new Map());
}

Which is fine, but I'm not sure if it's performant or even the best way. I am attracted to Maps for their iteration capabilities (Object.keys() is cumbersome and ugly to constantly call), their adherence to order insertion, and especially their allowance of any value as a key but they do not seem nearly as conducive to pure operations as plain Objects are.

For instance, if I want to add a property to an object purely:

const object = { foo: 'bar' }
const newObject= { ...object, fooFoo: 'barBar' }

I'm wondering if there are some Map operations I'm not wary of that might help facilitate working with them purely, or maybe even a small utility library. Any help is appreciated!

Robbie Milejczak
  • 5,664
  • 3
  • 32
  • 65
  • 1
    Checkout [Immutable.js](https://facebook.github.io/immutable-js/) – 4castle Jan 25 '19 at 18:23
  • ew no thank you. sorry, not sure if you have ever worked with immutable but it is a nightmare and way too cumbersome for what I'm going for – Robbie Milejczak Jan 25 '19 at 18:24
  • I wouldn't recommend it if I didn't strongly disagree with you. – 4castle Jan 25 '19 at 18:29
  • I haven't worked with it in a long time so maybe it's been improved, but I remember it being a huge headache. I guess I'll keep it in mind, maybe it's worth another chance if you feel so strongly – Robbie Milejczak Jan 25 '19 at 18:34
  • 1
    You can make new Map basing on the old one (as well as Set from Set). Just make `var m = new Map()` make some values then `var n = new Map(m)` – Sergey Jan 25 '19 at 18:57

1 Answers1

1

I would recommend to use Maps by their iterator interfaces. Sure, creating lots of temporary immutable Maps won't be faster than using them mutably, but iterators should still be faster than doing everything with array conversions.

Using these helper functions, your code could look like

function cloneOmit(map, keys) {
  const predicate = Array.isArray(keys)
    ? Set.prototype.has.bind(new Set(keys))
    : k => k === keys

  return new Map(filter(map.entries(), ([key, value]) => !predicate(key)));
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375