gpt4 book ai didi

javascript - 以函数式编程方式将 props 从 obj 复制到 obj

转载 作者:行者123 更新时间:2023-11-30 14:15:10 24 4
gpt4 key购买 nike

我有这些接口(interface):

  export interface QueryObject {
id: ID;
path: string[];
filters: Filters;
}

export interface Filters {
state: string;
localeID: string;
role: string;
}

并尝试提出一种函数式编程解决方案,以便仅将存在的属性和具有值的属性从 tmp 对象复制到现有数据模型。现在,.. 显然这是行不通的。 Filters 将被完全覆盖,同时丢失属性 localeIDrole

  let queryObject: QueryObject;
let filters: Filters = { state: 'GB'}; // this obviously gives an error on Interface implementation
queryObject.filters = filters;

现在我正在获取原始对象,遍历该属性并用更新后的值覆盖它。

  const queryObject: QueryObject = _.cloneDeep(this.queryObject);
queryObject.filters.state = state; // 'GB'
this.portareService.update(queryObject, this.portareQuery.getActiveId());

最好用 Object.assign 或传播 ... 解决方案来解决这个问题,例如:

{
return ...createQueryObject, updatedQueryObject
}

我知道如何通过使用循环的函数来做到这一点,但正在寻找一种函数式编程方法来解决这个问题。

最佳答案

您可以为 QueryObjectFilters 实现一个 concat 方法。在 concat 中,您定义要使用的“合并逻辑”。 QueryObject 在内部调用 Filters 的 concat 方法。

concat 方法中,您可以使用扩展语法或任何其他逻辑来确保创建新对象并且不会改变任何内容。

通过添加一个 empty 构造函数,您可以轻松地开始在 reduce 或其他自动合并中使用这些连接器。

我找到了 this blog post on Semigroups by Tom Harding super 鼓舞人心。 This post about Monoids有一些关于 empty 部分的信息。

const QueryObject = ({id = null, path = null, filters = Filters.empty() })=> ({ 
id,
path,
filters,

concat: other => QueryObject({
id: other.id || id,
path: other.path || path,
filters: filters.concat(other.filters)
}),

toString: () => `QueryObject(${id}, ${path}, ${filters.toString()})`
});

QueryObject.empty = () => QueryObject({});
QueryObject.merge = (x, y) => x.concat(y);



const Filters = ({ state = null, localeID = null, role = null }) => ({
state,
localeID,
role,

concat: other => Filters({
state: other.state || state,
localeID: other.localeID || localeID,
role: other.role || role
}),

toString: () => `Filters(${state}, ${localeID}, ${role})`
});

Filters.empty = () => Filters({});
Filters.merge = (x, y) => x.concat(y);


const userFilter = Filters({ role: "User" });
const gbFilter = Filters({ localeID: "GB" });

const filterSettings = [userFilter, gbFilter];
const mergedFilter = filterSettings.reduce(Filters.merge, Filters.empty());

console.log(
"Merged Filter:",
mergedFilter.toString()
);

// Some base query
const accountQuery = QueryObject({ id: "CUSTOM_Q_1", path: "/accounts" });

// Derived queries
const userQuery = accountQuery.concat(QueryObject({ filters: userFilter }));
const gbQuery = accountQuery.concat(QueryObject({ filters: gbFilter }));

console.log(
"User Query:",
userQuery.toString()
);

console.log(
"Brittish Users Query",
userQuery.concat(gbQuery).toString()
);

编辑:当然,没有“理论”,还有更通用的:

const uniques = xs => Array.from(new Set(xs));

const nullMergeStrategy = (obj1, obj2) =>
uniques(
Object.keys(obj1)
.concat(Object.keys(obj2))
).reduce(
(acc, k) => Object.assign(acc, { [k]: obj2[k] || obj1[k] }),
{}
);


const Filter = ({ state = null, localeID = null, role = null }) =>
({ state, localeID, role });

const userFilter = Filter({ role: "User" });
const gbFilter = Filter({ localeID: "GB" });

console.log(
nullMergeStrategy(userFilter, gbFilter)
)

关于javascript - 以函数式编程方式将 props 从 obj 复制到 obj,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53706596/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com