首页 > 解决方案 > new Map() 状态获取特定键

问题描述

我有一个状态 checkedItems: new Map();

当我尝试 console.log(checkedItem) 我得到这个:

地图(3){“1”=>真,“1.5”=>真,“2”=>假}

我怎样才能在数组中只得到真正的一个。

标签: javascriptreactjs

解决方案


映射具有entries()返回键值对上的迭代器的方法。迭代器是惰性的,所以你必须使用它来转换它。一种方法是变成一个数组,然后使用Array#filterandArray#map获取密钥:

Array.from(checkedItems.entries())
    .filter(([key, value]) => value)
    .map(([key]) => key)

但是,有一种更好的方法可以使用生成器懒惰地做到这一点:

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));

这只会在最后生成一个数组。

和生成filtermap功能可以组合在一起

const onlyTrueKeys = map(
  ([key]) => key,
  filter(
    ([key, value]) => value,
    checkedItems.entries()
  )
);

但是部分应用然后使用辅助函数组合它们可能更容易:

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);

如果您愿意,也可以将其制成一个类:

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());


推荐阅读