我应该如何在函数式编程中根据不同的条件使用不同的逻辑对对象内的列表进行排序

2024-03-26

考虑到我们有一个“api_fetchData”,它从服务器获取数据,并且基于路由,它可以是表或树,而且我们有两个状态,我们应该根据接收到的数据更新它们。我应该注意,如果数据是一个表,我们应该按优先级对它的记录进行排序。我想知道我应该如何以函数编程方式做到这一点(例如使用 ramda 或...)

 const tree=null;

and

const table = null:

//table

 {
        type: "table",
        records: [
          {
            id: 1,
            priority: 15
          },
          {
            id: 2,
            priority: 3
          }
        ]
}

//tree

{
        type: "tree",
        children: [
          {
            type: "table",
            records: [
              {
                id: 1,
                priority: 15
              },
              {
                id: 2,
                priority: 3
              }
            ]
          }
        ]
  }

这就是我所做的:

//定义实用程序

  const Right = x => ({
    map: f => Right(f(x)),
    fold: (f, g) => g(x),
    inspect: x => `Right(${x})`
  });
  const Left = x => ({
    map: f => Left(x),
    fold: (f, g) => f(x),
    inspect: x => `Left(${x})`
  });
  const fromNullable = x => (x != null ? Right(x) : Left(null));
  const state = reactive({
    path: context.root.$route.path,
    tree: null,
    table: null
  });

// 最终代码:

  const fetchData = () => {
    return fromNullable(mocked_firewall[state.path])
      .map(data =>
        data.type === "tree"
          ? (state.tree = data)
          : (state.table = R.mergeRight(data, {
              records: prioritySort(data.records)
            }))
      )
      .fold(
        () => console.log("there is no data based on selected route"),
        x => console.log(x)
      );
  };

你这里有几个问题 -

  1. 安全地访问不确定对象上的深层嵌套数据
  2. 使用函数技术对复杂数据数组进行排序
  3. safely 并且一成不变地更新不确定对象上的深层嵌套数据

1. Using .map and .chain是低级的,当语法变得痛苦时应该添加额外的抽象 –

const state =
  { tree:
      { type: "sequoia"
      , children: [ "a", "b", "c" ]
      }
  }

recSafeProp(state, [ "tree", "type" ])
  .getOrElse("?") // "sequoia"

recSafeProp(state, [ "tree", "foobar" ])
  .getOrElse("?") // "?"

recSafeProp(state, [ "tree", "children", 0 ])
  .getOrElse("?") // "a"

recSafeProp(state, [ "tree", "children", 1 ])
  .getOrElse("?") // "b"

recSafeProp(state, [ "tree", "children", 99 ])
  .getOrElse("?") // "?"

我们可以实施recSafeProp轻松地,发明我们自己的便利功能,safeProp, 一路上 -

const { Nothing, fromNullable } =
  require("data.maybe")

const recSafeProp = (o = {}, props = []) =>
  props.reduce // for each props as p
    ( (r, p) => // safely lookup p on child
        r.chain(child => safeProp(child, p))
    , fromNullable(o) // init with Maybe o
    )

const safeProp = (o = {}, p = "") =>
  Object(o) === o // if o is an object
    ? fromNullable(o[p]) // wrap o[p] Maybe
    : Nothing()  // o is not an object, return Nothing

2. The Comparison模块。您似乎对功能模块很熟悉,所以让我们开始吧 –

const { empty, map } =
  Comparison

const prioritySort =
  map(empty, record => record.priority || 0)

// or...
const prioritySort =
  map(empty, ({ priority = 0}) => priority)

myarr.sort(prioritySort)

如果你想要不可变的排序 –

const isort = ([ ...copy ], compare = empty) =>
  copy.sort(compare)

const newArr =
  isort(origArr, proritySort)

这是Comparison模块。它被介绍于本次问答 https://stackoverflow.com/a/61049318/633183。如果您有兴趣了解如何以实用的方式制作复杂的分类器,请查看此处 –

const Comparison =
  { empty: (a, b) =>
      a < b ? -1
        : a > b ? 1
          : 0
  , map: (m, f) =>
      (a, b) => m(f(a), f(b))
  , concat: (m, n) =>
      (a, b) => Ordered.concat(m(a, b), n(a, b))
  , reverse: (m) =>
      (a, b) => m(b, a)
  , nsort: (...m) =>
      m.reduce(Comparison.concat, Comparison.empty)
  }

const Ordered =
  { empty: 0
  , concat: (a, b) =>
      a === 0 ? b : a
  }

组合分拣机 –

const { empty, map, concat } =
  Comparison

const sortByProp = (prop = "") =>
  map(empty, (o = {}) => o[prop])

const sortByFullName =
  concat
    ( sortByProp("lastName")  // primary: sort by obj.lastName
    , sortByProp("firstName") // secondary: sort by obj.firstName
    )

data.sort(sortByFullName) // ...

可组合式分拣机 –

const { ..., reverse } =
  Comparison

// sort by `name` then reverse sort by `age`&nbsp;&ndash;
data.sort(concat(sortByName, reverse(sortByAge)))

功能原理 –

// this...
concat(reverse(sortByName), reverse(sortByAge))

// is the same as...
reverse(concat(sortByName, sortByAge))

也 -

const { ..., nsort } =
  Comparison

// this...
concat(sortByYear, concat(sortByMonth, sortByDay))

// is the same as...
concat(concat(sortByYear, sortByMonth), sortByDay)

// is the same as...
nsort(sortByYear, sortByMonth, sortByDay)

3.这里最容易实现的目标是不可变.js https://immutable-js.github.io/immutable-js/。如果以后有更多时间,我将展示针对特定问题的低保真方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我应该如何在函数式编程中根据不同的条件使用不同的逻辑对对象内的列表进行排序 的相关文章

  • NodeJS 最佳实践:流量控制错误?

    在 Node js 中 我应该使用错误来进行流程控制 还是应该更像异常一样使用它们 我正在 Sails js 中编写一个身份验证控制器和一些单元测试 目前 我的注册方法检查是否存在具有相同用户名的用户 如果用户已存在并具有该用户名 我的模型
  • JSON.stringify / 解析带有引号的奇怪内容

    我在解析一些包含引号的 JSON 时遇到了一个奇怪的小问题 我正在使用本机 JSON stringify 和 JSON parse 函数来执行此操作 如果我将一个对象 其中有引号的对象 字符串化 它们就会像人们所期望的那样被转义 如果我然后
  • 附加的新行的行为与前一行(行)不同

    我有一个 HTML 表格 里面有几个td as input字段 我的表格是动态的 当页面加载时 我将附加表格的第一行并且focus在第一个输入字段中 就我而言 即Item Name 我的行中有 3 个输入字段 它们是Item Name Un
  • IE toDataUrl() 安全错误

    我需要从画布上获取图片 因此我从 Amazon S3 获取图像 我在那里启用了跨源资源共享 CORS 并将 croseOrigin 属性 匿名 设置为 img 它适用于 Chrome 和FireFox 但在 IE 上 我通过调用 toDat
  • 使用 Jest 模拟延迟() RxJS

    有没有简单的方法来嘲笑delay 例如 带有假时间的可观察对象中的 RxJS 方法 我有这个方法 register user return this checkLog user delay 500 flatMap 当我删除时delay 方法
  • Protractor 中 element(...) 和 element(...).getWebElement() 之间的区别

    为什么我们需要element getWebElement over element 当两者的工作原理完全相同时 为什么两个 API 具有相同的功能 Protractor是一个方便的包装WebDriverJS javascript 硒绑定 e
  • Next.js 使用 getServerSideProps 如何将属性从页面传递到组件?

    我正在尝试获取coingecko api访问比特币的实时价格 我正在尝试将 getServerSideProps 的返回道具传递给我的
  • Google Adsense 中的 Javascript 错误

    在我的几个运行 AdSense 的网站上 我收到以下错误 无法将消息发布到 http googleads g doubleclick net http 5Dgoogleads g doubleclick net 收件人有来源http www
  • 不显眼的 Javascript 混淆了事件处理

    你知道我最喜欢引人注目的 javascript 的什么吗 当你触发一个事件时 你总是知道它会做什么 a a 现在每个人都在喝这种不引人注目的酷爱饮料 这一点就不那么明显了 对绑定事件的调用可以发生在页面中包含的任意数量的 javascrip
  • onclick 和 href="javascript:函数名 之间有什么区别?

    有什么区别吗 1 a href Link1 a and 2 a href Link2 a 会以某种方式影响页面性能吗 如果您的元素实际上不应该将用户链接到某个地方 不要将其设为锚元素 如果您正在使用 a 标签只是为了改变下划线 光标 不要
  • 未捕获的类型错误:$(...).lightGallery 不是函数

    当我尝试单击该链接时 它会在浏览器控制台中显示 Uncaught TypeError lightGallery is not a function anonymous function index html 250dispatch jque
  • 释放 Javascript 中未附加 DOM 节点使用的内存

    作为我的应用程序的一部分 我将一组小型 Dom 节点放在一起 这些节点不会一次全部显示 我将它们存储在内部数组中 用户可以调用它们的显示 在这种情况下 我将它们重新设置为用于显示它们的 div 这一切都很好 但是 当需要用新的替换所有它们时
  • 当用户输入时将输入值转换为货币格式

    我无法将输入值转换为货币格式 我想在用户键入数字 5 000 00 125 000 00 时自动添加千位和小数分隔符 这是我的代码 input CurrencyInput on blur focus keyup function this
  • RegEx 从 CSS 背景样式中提取 URL

    我有一个这种形式的字符串 url http www example com imgs backgrounds bg80 jpg repeat scroll 10 0 transparent 这是来自某个元素的 CSS 样式 该元素目前在页面
  • 如何在 PhantomJS 中使用 JavaScript 检测网页上的声音?

    我需要检测带有横幅的网页中的所有声音 我怎样才能做到这一点 我查看 PhantomJS 但找不到浏览器声音的 API PhantomJS 1 x 和 2 不支持 Flash
  • 如何包含和使用 math.js

    我正在尝试使用 math js http mathjs org docs reference functions inv html http mathjs org docs reference functions inv html 但我不知
  • 如何在类组件中使用react-router-dom v6导航

    我安装了react router dom v6 我想在以前版本的react router dom v5中使用基于类的组件this props history 在执行某些操作后适用于重定向页面 但此代码不适用于 v6 在react route
  • Google Map API V3 - 单击标记以叠加形式显示更多信息内容(如 Google 地图中一样)

    我们使用 Google Map Api V3 在 HTML 容器中加载 google 地图 我们有一个位置搜索表格 提交后 我们将获取可用位置并在地图中设置标记 加载标记后 单击每个标记时我们需要显示标题 地址详细信息和设计 就像我们在谷歌
  • 当用户滚动经过页面的特定部分时,jQuery 触发操作

    大家好 我需要一个 jQuery 操作来在用户滚动经过页面上的某些位置时触发 这对于 jQuery 来说是可能的吗 我查看了 jQuery API 中的 scroll 我认为这不是我需要的 每次用户滚动时它都会触发 但我需要它在用户经过某个
  • JavaScript 中的异步事件处理

    我在防止双重 多重 方面遇到问题eventListener代码中的处理 var locked button addEventListener click function if locked return locked true calcu

随机推荐