通过功能性编程方式将道具从obj复制到obj

San Jay Falcon

我有这些接口:

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

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

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

  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
}

我知道如何使用使用循环的函数来执行此操作,但是正在寻找使用函数式编程的方法。

用户名

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

在这些concat方法中,您可以使用传播语法或任何其他逻辑来确保创建新对象,并且您不会对任何内容进行突变。

通过添加empty构造函数,您可以轻松地在areduce或其他自动合并中开始使用那些串联器

在汤姆·哈丁(Tom Harding)的Semigroups博客上找到了这篇超级启发的博客文章这篇有关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)
)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

将div复制到obj并对其进行操作

Visual Studio构建失败:无法将exe文件从obj \ debug复制到bin \ debug

如何将ABC值从JS-OBJ复制到HTML集合成员的innerHTML?

错误1无法将文件“ obj \ Debug \ SourceProject.exe”复制到“ bin \ Debug”

如何以编程方式将文件复制,复制到SD?

以编程方式将CSS类属性复制到新类

如何以编程方式将文件复制到另一个目录?

如何以编程方式将文件复制到另一个目录?

iOS Swift 3以编程方式将文件复制到iCloud驱动器

Elisp以编程方式复制到剪贴板

以功能性方式拆分流

单击后如何以编程方式将异步相关内容复制到剪贴板?

.Net MVC 发布错误 - 将文件 template\hts-cache\doit.log 复制到 obj\Release\Package\PackageTmp\template\hts-cache\doit.log 失败

如何在功能性HOC中访问道具?

向功能性React组件子代添加渲染道具

简单的Node / Express应用程序,功能性编程方式(如何处理JavaScript中的副作用?)

将C ++ Lambda复制到功能指针参考

将存储在变量中的数据数组传递到 JavaScript 中的功能性混合模式 OOP

榆木/将道具传递到组件的功能方式

用功能性编程方法代替foreach循环

什么是(功能性)反应式编程?

通过 Ansible 将文件复制到 docker 容器

将通过加密从PHP复制到JS

通过 Gradle 将文件复制到构建目录

通过循环将数据复制到整数指针数组?

通过拖放将文件复制到`/ usr / local`

如何通过ssh将jpg复制到本地

如何以功能性方式替换循环?

以功能性方式重写Scala中的集合填充模拟