Reputation: 113
I have a state checkedItems: new Map();
and when I'm trying to console.log(checkedItem) i get this:
Map(3) {"1" => true, "1.5" => true, "2" => false}
How can I get only the true one in an array.
Upvotes: 3
Views: 247
Reputation: 28969
Maps have the entries()
method which returns an iterator over the key-value pairs. Iterators are lazy, so you have to consume it to transform it. One way is to turn into an array and then use Array#filter
and Array#map
to get the keys:
Array.from(checkedItems.entries())
.filter(([key, value]) => value)
.map(([key]) => key)
However, there is a better way to do this lazily using generators:
function* filter(predicate, it) {
for (const item of it) {
if (predicate(item))
yield item;
}
}
function* map(fn, it) {
for (const item of it) {
yield fn(item);
}
}
const checkedItems = new Map()
.set("1" , true)
.set("1.5", true)
.set("2" , false);
const iterator = checkedItems.entries();
const onlyTrue = filter(([key, value]) => value, iterator);
const onlyTrueKeys = map(([key]) => key, onlyTrue);
console.log(Array.from(onlyTrueKeys));
This will only generate a single array at the end.
The filter
and map
generator functions can be combined together
const onlyTrueKeys = map(
([key]) => key,
filter(
([key, value]) => value,
checkedItems.entries()
)
);
But it might be easier to partially apply and then compose them with a helper function:
function* filter(predicate, it) {
for (const item of it) {
if (predicate(item))
yield item;
}
}
function* map(fn, it) {
for (const item of it) {
yield fn(item);
}
}
function transform(iterator, ...transformers) {
return transformers.reduce((it, transform) => transform(it), iterator);
}
const checkedItems = new Map()
.set("1" , true)
.set("1.5", true)
.set("2" , false);
const onlyTrueKeys = transform(
checkedItems.entries(),
filter.bind(null, ([key, value]) => value),
map.bind(null, ([key]) => key),
Array.from
);
console.log(onlyTrueKeys);
This can also be made into a class, if you prefer:
function* filter(it, pred) {
for (const item of it) {
if (pred(item))
yield item;
}
}
function* map(it, fn) {
for (const item of it) {
yield fn(item);
}
}
class LazyTransformer {
constructor(iterator) {
this.iterator = iterator;
}
filter(predicate) {
this.iterator = filter(this.iterator, predicate);
return this;
}
map(fn) {
this.iterator = map(this.iterator, fn);
return this;
}
toArray() {
return Array.from(this.iterator);
}
}
const checkedItems = new Map()
.set("1" , true)
.set("1.5", true)
.set("2" , false);
const transformer = new LazyTransformer(checkedItems.entries());
transformer
.filter(([key, value]) => value)
.map(([key]) => key);
console.log(transformer.toArray());
Upvotes: 2