如何让这个功能更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)));
我在下面写了这个函数,它按产品类型和货币类型转换传递的产品数组
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)));