[Typescript] Dictionary map, filter and reduce

const fruits = {
  apple: { color: "red", mass: 100 },
  grape: { color: "red", mass: 5 },
  banana: { color: "yellow", mass: 183 },
  lemon: { color: "yellow", mass: 80 },
  pear: { color: "green", mass: 178 },
  orange: { color: "orange", mass: 262 },
  raspBerry: { color: "red", mass: 4 },
  cherry: { color: "red", mass: 5 },
}

interface Dict<T> {
  [k: string]: T
}

// array.prototype.map, but for Dict
function mapDict<T, S>(input: Dict<T>, transform: (item: T, key: string) => S): Dict<S> {
  const obj: Dict<S> = {};
  for (let x in input) {
    obj[x] = transform(input[x], x);
  }
  return obj;
}
// Array.prototype.filter, but for Dict
function filterDict<T>(input: Dict<T>, predict: (item: T) => boolean): Dict<T> {
  const obj: Dict<T> = {};
  for (let x in input) {
    if (predict(input[x])) {
      obj[x] = input[x];
    }
  }
  return obj; 
}
// Array.prototype.reduce, but for Dict
function reduceDict<T, V>(input: Dict<T>, reducer: (acc: V, curr: T) => V, initialValue: V): V {
  return Object.keys(input)
    .reduce((acc, curr) => {
      return reducer(acc, input[curr]);
    }, initialValue)
}

 

Test:

// MAP
const fruitsWithKgMass = mapDict(fruits, (fruit, name) => ({
  ...fruit,
  kg: 0.001 * fruit.mass,
  name,
}))
const lemonName: string = fruitsWithKgMass.lemon.name
// @ts-ignore-error
const failLemonName: number = fruitsWithKgMass.lemon.name
assertOk(
  fruitsWithKgMass,
  "[MAP] mapDict returns something truthy"
)
assertEquals(
  fruitsWithKgMass.cherry.name,
  "cherry",
  '[MAP] .cherry has a "name" property with value "cherry"'
)
assertEquals(
  fruitsWithKgMass.cherry.kg,
  0.005,
  '[MAP] .cherry has a "kg" property with value 0.005'
)
assertEquals(
  fruitsWithKgMass.cherry.mass,
  5,
  '[MAP] .cherry has a "mass" property with value 5'
)
assertEquals(
  Object.keys(fruitsWithKgMass).length,
  8,
  "[MAP] fruitsWithKgMass should have 8 keys"
)

// FILTER
// only red fruits
const redFruits = filterDict(
  fruits,
  (fruit) => fruit.color === "red"
)
assertOk(
  redFruits,
  "[FILTER] filterDict returns something truthy"
)
assertEquals(
  Object.keys(redFruits).length,
  4,
  "[FILTER] 4 fruits that satisfy the filter"
)
assertEquals(
  Object.keys(redFruits).sort().join(", "),
  "apple, cherry, grape, raspBerry",
  '[FILTER] Keys are "apple, cherry, grape, raspBerry"'
)

// REDUCE
// If we had one of each fruit, how much would the total mass be?
const oneOfEachFruitMass = reduceDict(
  fruits,
  (currentMass, fruit) => currentMass + fruit.mass,
  0
)
assertOk(
  redFruits,
  "[REDUCE] reduceDict returns something truthy"
)
assertEquals(
  typeof oneOfEachFruitMass,
  "number",
  "[REDUCE] reduceDict returns a number"
)
assertEquals(
  oneOfEachFruitMass,
  817,
  "[REDUCE] 817g mass if we had one of each fruit"
)

 

相关文章

我最大的一个关于TypeScript的问题是,它将原型的所有方法(无...
我对React很新,我正在尝试理解子组件之间相互通信的简洁方法...
我有一个非常简单的表单,我将用户电子邮件存储在组件的状态,...
我发现接口非常有用,但由于内存问题我需要开始优化我的应用程...
我得到了一个json响应并将其存储在mongodb中,但是我不需要的...
我试图使用loadsh从以下数组中获取唯一类别,[{"listing...