我最近将一些使用常规对象的代码转换为新的es6 module MyListMonad where
import Control.Monad
data List a = Empty | Cons a (List a) deriving (Show, Eq)
instance Functor List where
fmap = liftM -- boilerplate
instance Applicative List where
pure x = Cons x Empty -- put definition of `return` here
(<*>) = ap
instance Monad List where
return = pure -- boilerplate
(>>) = (*>) -- boilerplate
xs >>= f = myConcat (myMap f xs) -- bind definition here
myConcat :: List (List a) -> List a
myConcat (Cons lst rest) = myAppend lst (myConcat rest)
myConcat Empty = Empty
myAppend :: List a -> List a -> List a
myAppend (Cons x rest) ys = Cons x (myAppend rest ys)
myAppend Empty ys = ys
myMap :: (a -> b) -> List a -> List b
myMap f (Cons x rest) = Cons (f x) (myMap f rest)
myMap _ Empty = Empty
test = do x <- Cons 1 $ Cons 2 $ Cons 3 Empty
y <- Cons 4 $ Cons 5 $ Empty
return (x * y)
类。我很快遇到了一个问题,虽然Map
课程包含Map
Array
,但它不包含forEach
方法以及其他许多Array.prototype
方法
为了给出一些上下文,使用常规JS对象的原始代码看起来像这样:
var map = {
entry1: 'test',
entry2: 'test2'
};
Object.keys(map).some(key => {
var value = map[key];
// Do something...found a match
return true;
});
Map
类确实包含some
方法,但遗憾的是这会返回entries
个对象。这不包括访问Array.prototype
方法的任何简单方法。
我很好奇是否有一种干净的方法可以做到这一点,或者我是在咆哮错误的树。
答案 0 :(得分:3)
使用Map#values
获取值的迭代器,使用spread syntax
或Array#from
(样式问题)将迭代器转换为数组:
const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
const result = [...map.values()].some((value) => value > 2);
console.log(result);
如@Paulpro comment所述,您可以使用相同的方法来迭代Map#entries
和Map#keys
。例如,使用Array#reduce
将Map转换为对象。由于Array#from
调用Map#entries
,我们无需明确调用它:
const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
const result = Array.from(map.entries()).reduce((obj, [key, value]) => {
obj[key] = value;
return obj;
}, {});
console.log(result);
答案 1 :(得分:1)
在Array.from
对象上调用Map
并在其上调用some
:
Array.from(map).some(([key, value]) => /* something */ true)
当然这非常低效。一个更好的想法是定义 在任何迭代器上工作的some
函数,例如Map
提供的函数:
function some(it, pred) {
for (const v of it)
if (pred(v))
return true;
return false;
}
some(map.values(), value => /* something */ true)
答案 2 :(得分:0)
似乎解决这个问题的最简单方法是将Map
的条目转换为Array
的某种方式,但我没有找到任何干净的方法来执行此操作。目前我的解决方案是定义一个这样的方法来进行转换:
mapEntriesAsArray (map) {
const entries = [];
map.forEach((entry, type) => entries.push([type, entry]));
return entries;
}
也许我可以把它扔在Map.prototype
上,但这看起来非常hacky,我确信我必须通过添加一个d.ts文件或其他东西来使用它来使用它而不会出错。< / p>