如何让这个功能更reusable/specific/better设计?

How to make this function more reusable/specific/better design?

我在下面写了这个函数,它按产品类型和货币类型转换传递的产品数组

function getProductsByCurrency(products, type, exchangeRate = 1) {
    var productsRetrieved = products.map(item => ({id: item.id,
        name: item.name,
        price: (item.price * exchangeRate).toFixed(2),
        type: type}));
    return productsRetrieved;       
}

是否可以将功能分解得更具体一些?或者以更好的方式设计它? 例如,通过将其命名为 getProductsByCurrency 它看起来不正确,因为如果我以默认汇率使用它,我可以传递 books 数组以检索具有 'books' 类型且与汇率无关的产品。 也许有办法使用偏函数(FP)?

编辑: 为我想要实现的目标添加更多上下文。

假设我有三类产品(手机、化妆品、书籍) 来自三个资源。我需要按不同货币(productsinUSD、productsinAUD、productsinPounds)创建三个所有产品的合并数组

还使用以下函数合并数组

    function concatProducts(arr) {
        return [].concat.apply([], arr);
    }

所以我调用了 3 次 getProductsByCurrency 以按产品类型和货币(汇率)转换它们并将这些值作为数组传递以连接它们以实现 productsinUSD。并重复以获取 productsinAUD、productsinPounds。

也可以输入字符串值(例如:'mobiles')

这取决于您输入这些函数的数据类型。如果您将传递不同的对象数组(它们都具有 属性 类型),那么我认为您将拥有一个按类型(或任何其他 属性 和条件之间常见的条件过滤数组的函数不同的数据集)。您可以将过滤函数与映射函数链接起来。您的映射函数似乎需要特定于货币,因为您正在从对象中提取某些道具,而不是在 return 它之前计算一些值。

希望对您有所帮助

首先,您发布的函数没有任何错误。有些事情我会做不同的事情,但我不会假装这不是分裂头发。

const processItem = (type, exchangeRate = 1) => ({
  id,
  price,
  name,
}) => ({
  id,
  name,
  type,
  price: (price * exchangeRate).toFixed(2),
});

我们有一个函数接受一个类型和一个可选的 exchangeRate,returns 一个函数可以将单个项目转换为您想要的形式。这就是鲍勃在评论中所说的。我还在项目上使用了对象解构,在结果上使用了 属性 shorthand 以使代码更清晰。现在我们可以将它映射到各种类别的东西上:

const results = [
   ...mobilePhones.map(processItem('phone')),
   ...cosmetics.map(processItem('cosmetics')),
   ...books.map(processItem('book')),
];

如果您出于其他目的需要临时结果,只需将它们填充到 vars 中即可,但为简单起见,我已将它们直接分散到结果数组中。

虽然这比您发布的代码质量帽子戏法更短、更清晰、更灵活,但我想重申,我看到的方式比您发布的功能更糟糕。

您所做的没有任何问题,但您还可以再创建 3 个函数来调用它们,然后用相应的类型调用 getProductsByCurrency

var example = JSON.parse(`[{"id":1,"name":"1","price":5},{"id":2,"name":"2","price":15},{"id":3,"name":"3","price":20}]`);

function getProductsByCurrency(type, products, exchangeRate = 1) {
  return products.map(item => ({
    id: item.id,
    name: item.name,
    price: (item.price * exchangeRate).toFixed(2),
    type: type
  }));
}

function getPhonesByCurrency() {
  return getProductsByCurrency("phone", ...arguments);
}

function getCosmeticsByCurrency() {
  return getProductsByCurrency("cosmetic", ...arguments);
}

function getBooksByCurrency() {
  return getProductsByCurrency("book", ...arguments);
}

console.log([].concat(getPhonesByCurrency(example), getCosmeticsByCurrency(example, 0.5), getCosmeticsByCurrency(example, 2)));

您可能还更喜欢将这 3 个函数包装在一个对象中(更整洁并有助于 IDE 自动完成)

var example = JSON.parse(`[{"id":1,"name":"1","price":5},{"id":2,"name":"2","price":15},{"id":3,"name":"3","price":20}]`);

function getProductsByCurrency(type, products, exchangeRate = 1) {
  return products.map(item => ({
    id: item.id,
    name: item.name,
    price: (item.price * exchangeRate).toFixed(2),
    type: type
  }));
}

const getByCurrency = {
  phones: function() {
    return getProductsByCurrency("phone", ...arguments);
  },
  cosmetics: function() {
    return getProductsByCurrency("cosmetic", ...arguments);
  },
  books: function() {
    return getProductsByCurrency("book", ...arguments);
  }
};

console.log([].concat(getByCurrency.phones(example), getByCurrency.cosmetics(example, 0.5), getByCurrency.books(example, 2)));