How to filter javascript map?

Given the ES6 card and the predicate function, how to safely remove all inappropriate elements for the card?


I could not find the official API function, but I can think of two implementations. The first does not attempt to delete in place, but instead creates a copy:

// version 1:
function filter(map, pred) {
  const result = new Map();
  for (let [k, v] of map) {
    if (pred(k,v)) {
      result.set(k, v);
    }
  }
  return result;
}

const map = new Map().set(1,"one").set(2,"two").set(3,"three");
const even = filter(map, (k,v) => k % 2 === 0);
console.log([...even]); // Output: "[ [ 2, 'two' ] ]"
Run codeHide result

Another removes in place. In my tests, this works, but I did not find a guarantee that changing the map will not break the iterator (for-of loop):

// version 2:
function deleteIfNot(map, pred) {
  for (let [k, v] of map) {
    if (!pred(k,v)) {
      map.delete(k);
    }
  }
  return map;
}

const map = new Map().set(1,"one").set(2,"two").set(3,"three");
deleteIfNot(map, (k,v) => k % 2 === 0);
console.log([...map]); // Output: "[ [ 2, 'two' ] ]"
Run codeHide result

Question:

  • Is the second version (removal in place) on all platforms correct?
  • Is there a better way to implement a filter in place? Maybe some official API that I missed?
+9
source share
3 answers

ES6 , .

API, ES6 .

, .

forEach, , .

, . , :

for (let k of map.keys()) {
  if (!(k % 2))
    map.delete(k);
}
+5

.filter(), , ES6 Map .filter. :

  • [, ].
  • .
  • .

:

const map0 = new Map([
  ['a', 1],
  ['b', 2],
  ['c', 3]
]);

const map1 = new Map(
  [...map0]
  .filter(([k, v]) => v < 3 )
);

console.info([...map1]) //[0: ["a", 1], 1: ["b", 2]]
+6

, .

// MAP EXAMPLE
const myMap = {
  "1G7JA": {
    id: 1,
    name: "Jack"
  },
  "H7GA0": {
    id: 2,
    name: "Betty"
  },
  "8JK12": {
    id: 3,
    name: "Mary"
  }
};

// CONVERT MAP TO ARRAY
const myArray = Object.values(myMap).filter(report=> report.user._id === userId);

// CONVERT ARRAY TO MAP
const arrayToMap = (array, element) => {
  const result = {};
  array.forEach(item => {
    result[Object.byString(item, element)] = item;
  });
  return result;
};

However, you convert the map into an array (lots of processing) that is easy to filter. It is counterproductive to use only on small arrays, where the need to save your list as an object weighs a good reason to use it.

Yours faithfully

Daniel

+1
source

Source: https://habr.com/ru/post/1693416/


All Articles