Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >从列表中提取,直到遇到副本

从列表中提取,直到遇到副本
EN

Stack Overflow用户
提问于 2015-02-26 16:39:03
回答 4查看 1.5K关注 0票数 3

在Haskell中,takeWhile允许从(潜在的无限)列表中获取条目,直到某个条件不满足为止。

但是,此条件不能依赖于列表中先前的条目。

在遇到第一个重复之前,我如何从(潜在的无限)列表中获得take条目,如本例所述?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
*Main> takeUntilDuplicate [1,2,3,4,5,1,2,3,4]
[1,2,3,4,5]
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-02-26 17:46:51

一种方法是在遍历列表时更新一段状态,类似于在命令式语言中所做的事情。这需要与State monad合作,如果这是你的第一次,它可能需要学习和玩耍,但是相信我,这是非常值得学习的。让我们从进口开始:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import Control.Monad.State
import Data.Set (Set)
import qualified Data.Set as Set

我们要保持的状态是元素的Set,直到列表中的那个点。因此,首先,让我们编写一对简单的State操作来管理可见的元素集:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- Add an element to the context Set
remember :: Ord a => a -> State (Set a) ()
remember a = modify (Set.insert a)

-- Test if the context set contains an element
haveSeen :: Ord a => a -> State (Set a) Bool
haveSeen a = do seen <- get
                return (a `Set.member` seen)

现在,我们将这两个操作合并为一个检查复制的操作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
isDuplicate :: Ord a => a -> State (Set a) Bool
isDuplicate a = do seen <- haveSeen a
                   remember a
                   return seen

您已经提到了takeWhile函数。我们将按照类似的思路来构建我们的解决方案。这是takeWhile的定义:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- different name to avoid collision
takeWhile' :: (a -> Bool) -> [a] -> [a]
takeWhile' _ [] =  []
takeWhile' p (a:as)
    | p a =  a : takeWhile p as
    | otherwise =  []

我们可以修改这个函数以处理一个谓词,该谓词将Bool封装在一个monad中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
takeWhileM :: Monad m => (a -> m Bool) -> [a] -> m [a]
takeWhileM _ [] = return []
takeWhileM p (a:as) = 
    do test <- p a
       if test
       then do rest <- takeWhileM p as
               return (a:rest)
       else return []

但是这里的关键区别在于,由于takeWhileM中的测试是一元的,所以我们可以从上面使用有状态的isDuplicate。因此,每次我们用isDuplicate测试列表中的一个元素时,我们还会在正在执行计算的Set中记录该元素。现在我们可以这样写takeUntilDuplicate了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
takeUntilDuplicate :: Ord a => [a] -> [a]
takeUntilDuplicate as = evalState (takeUntilDuplicate' as) Set.empty
    where takeUntilDuplicate' :: Ord a => [a] -> State (Set a) [a]
          takeUntilDuplicate' = takeWhileM (fmap not . isDuplicate)

示例使用(带有无限list参数):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 >>> takeUntilDuplicate (cycle [1..5])
 [1,2,3,4,5]

更妙的是,这些代码中有几段可以被重用来解决类似的问题。

票数 9
EN

Stack Overflow用户

发布于 2015-02-26 22:57:55

假设您正在处理Ord实例,您可以这样做。这与Luis Casillas's answer本质上是一样的,但是用折叠而不是State来表示。我们的每个答案都使用了一种不同的普遍适用的技术。路易斯对他的书作了很好的解释,我的经典解释是在格雷厄姆·赫顿的“关于折叠的普遍性和表现力的教程”中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import Data.Set (member)
import qualified Data.Set as S

takeUntilDuplicate :: Ord a => [a] -> [a]
takeUntilDuplicate xs = foldr go (const []) xs S.empty
  where
    go x cont set
      | x `member` set = []
      | otherwise      = x : cont (S.insert x set)

如果您实际上正在处理Int (或任何可以非常快地转换为Int的内容),则可以通过使用Data.IntSetData.HashSet而不是Data.Set来显著提高性能。

票数 5
EN

Stack Overflow用户

发布于 2015-02-26 16:59:49

您认为takeWhile不起作用是因为您没有单个元素的上下文信息,这表明了以下策略:获取它。

我的This答案提到了带有上下文的装饰操作,我称之为picks (因为它向您展示了如何选择一个要关注的元素)。这是我们应该对每一件容器都免费使用的一般装潢及其上下文操作。对于列表,它是

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
picks :: [x] -> [(x, ([x], [x]))] -- [(x-here, ([x-before], [x-after]))]
picks [] = []
picks (x : xs) = (x, ([], xs)) : [(y, (x : ys, zs)) | (y, (ys, zs)) <- picks xs]

对于无限大的列表,它是非常有效的,而我们则是这样做的。

现在和你一起去

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
takeUntilDuplicate :: Eq x => [x] -> [x]
takeUntilDuplicate = map fst . takeWhile (\ (x, (ys, _)) -> not (elem x ys)) . picks

(奇怪的是,如果没有给予上述类型的签名,上述一行就会因为Eq的模糊性而被拒绝。)我很想问一个关于它的问题。哦,这是单形限制。(真烦人。)

备注:表示picks使用snoc列表(在右边增长的列表)交付的“元素之前”组件非常有意义(我通常也会),更好地保持共享和从左到右的视觉效果。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28755554

复制
相关文章
Android网格视图(GridView)
GridView的一些属性: 1.android:numColumns=”auto_fit”   //GridView的列数设置为自动,也可以设置成2、3、4…… 2.android:columnWidth=”90dp "       //每列的宽度,也就是Item的宽度 3.android:stretchMode=”columnWidth"//缩放与列宽大小同步 4.android:verticalSpacing=”10dp”          //两行之间的边距 5.android:horizontal
欢醉
2018/01/22
1.6K0
Android网格视图(GridView)
Echarts隐藏背景的网格线
网格线未处理之前,默认是这样的,这个背景的网格线,我们现在如果不需要,就去掉吧。 Echarts隐藏背景的网格线属性 yAxis: { splitLine: {show: false}, }, 示例代
王小婷
2021/04/09
1.6K0
Echarts隐藏背景的网格线
模型选择–网格搜索
首先使用训练数据训练模型,然后使用交叉验证数据挑选最佳模型,最后使用测试数据测试模型是否完好。
全栈程序员站长
2022/09/27
6130
删除 WordPress 导航菜单的多余 CSS 选择器(id或class)
在默认情况下,WordPress 的导航菜单会输出很多如menu-item、menu-item-type-taxonomy、menu-item-object-category等加上 id 组成的CSS 选择器,无疑,对于一些人来说,这些选择器导致整个html 格式变得难看,看着碍眼的东西最好是将它去掉,之前Jeff 也曾有过一篇类似的文章《删除 WordPress 导航菜单的多余 CSS 选择器》,今天则介绍个通过添加过滤器来删除 WordPress 导航菜单的多余 CSS 选择器(id或class)的新方
Jeff
2018/01/19
1.6K0
删除 WordPress 导航菜单的多余 CSS 选择器(id或class)
SwiftUI:视图的显示和隐藏动画
SwiftUI最强大的功能之一是能够自定义视图的显示和隐藏方式。以前,您已经了解了如何使用常规if条件有条件地包含视图,这意味着当条件更改时,我们可以从视图层次结构中插入或移除视图。
韦弦zhy
2020/04/16
4.6K0
Emlog文章隐藏内容登陆后可见
其次将模板echo_log.php中log_content修改成login_to_view(log_content);即可,最后就是后台了。
用户8099761
2023/05/10
4640
Emlog文章隐藏内容登陆后可见
这个功能在群里面看到有用户需求,然后也忘记是谁需要的了,就先发到论坛给所有的Emer吧。 首先在模板module.php中增加已下代码:
用户8099761
2023/05/10
4600
jQuery 隐藏具有指定class属性值的元素
代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>前端</title> <style> .antzone{ width:200px; height:100px; background:#ccc; } </style> <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script> <script> $(document).ready(func
IT工作者
2022/02/17
5K0
如何隐藏tableHeaderView或tableFooterView
在项目中,因为同一页面结构体不同,头部是相同的结构,用了两个不同的tableView,头部是统一的view,但是发现tableView.tableHeaderView=_headerView只赋值一次,不支持来回赋值,打印出 NSLog(@"%@",_headerView.superview)仍然是上一个tableview视图。
honey缘木鱼
2019/11/04
1.1K0
ASP.NET Core 5.0 MVC中的视图分类及使用——布局视图、启动视图、导入视图、详细视图、分部视图
我们可以在这个页面,添加一些全局性的内容,比如全局变量等,然后在具体View页面使用这些变量值
明志德道
2023/10/21
4040
ASP.NET Core 5.0 MVC中的视图分类及使用——布局视图、启动视图、导入视图、详细视图、分部视图
右键添加隐藏或显示系统隐藏文件
我不喜欢长期显示着隐藏文件,这样看着目录结构比较乱,所以平时用的时候都是隐藏,而有的时候需要看一些隐藏的目录里面的内容,又需要显示出来,这样操作比较麻烦,所以在右键添加上 显示/隐藏 系统隐藏文件 功能,可以快速在某个目录下切换显示隐藏文件的状态,不必到资源管理器的菜单中再花几个步骤去调整了。在网上搜索了一些方法,下面是最靠谱的,只不过他是显示隐藏文件拓展名,我稍微修改了一下,成了显示和隐藏系统隐藏文件功能。
我与梦想有个约会
2023/10/21
4580
右键添加隐藏或显示系统隐藏文件
ASP.NET MVC编程——视图
1Razon语法 使用@符号后接C#或VB.NET语句的方式。 基本规则 1)变量 @后直接变量即可 2)代码块 为使用表达式或多行代码,@后跟大括号将多行代码包括在大括号中 3)“+” 对于加号连接的两个字符串变量或属性,使用小括号将他们括起来 4)插入HTML或文字 每一行前面加上“@:” 5)使用注释 使用@*和*@将要注释的部分包起来 6)用@@在页面上显示@ @using 在一个View中引入此页所需程序集的命名空间。 还可以在web.config中配置命名空间,不过将对所有的View起作用。 <
甜橙很酸
2018/03/30
3.1K0
ASP.NET Core MVC 视图
布局用于提供各个页面所需的公共部分,如:菜单、页头、页尾等。在ASP.NET Core中默认的布局文件是位于/Views/Shared文件夹下的_Layout.cshtml文件:
雪飞鸿
2019/05/19
2.2K0
ASP.Net MVC视图间的跳转
1:同一控制器间视图跳转 发现一个贼坑的地方,比如添加Home控制器,然后在views的home文件夹里添加Index视图和Second视图,在Index视图里想要通过超链接跳转到Second视图,需要这样写:
全栈程序员站长
2022/09/15
1.6K0
ASP.Net MVC视图间的跳转
小知识科普:随处可见的短ID和短网址
早上收到快递小哥的短信说快递被放在了A地的丰巢快递柜,然鹅这个快递柜我并不知道在哪里。
帅地
2019/11/22
1.7K0
小知识科普:随处可见的短ID和短网址
input:文件选择和隐藏
新建 html 文件 17-inputFile.html,编写下方程序,运行看看效果吧
鹤川
2023/03/21
1.4K0
ASP.NET MVC 5 - 视图
在本节中,你要去修改HelloWorldController类,使用视图模板文件,在干净利索地封装的过程中:客户端浏览器生成HTML。 您将创建一个视图模板文件,其中使用了ASP.NET MVC 3所引入的Razor视图引擎(Razor view engine)。Razor视图模板文件使用.cshtml文件扩展名,并提供了一个优雅的方式来使用C#语言创建所要输出的HTML。用Razor编写一个视图模板文件时,将所需的字符和键盘敲击数量降到了最低,并实现了快速,流畅的编码工作流程。 当前在控制器类中的Inde
葡萄城控件
2018/01/10
3.2K0
ASP.NET MVC 5 - 视图
Gizmos菜单_gi clamp
在现场查看和游戏视图都有一个小玩意儿菜单。点击小玩意儿场景视图或游戏视图访问工具栏中的按钮,小玩意儿菜单。
全栈程序员站长
2022/09/20
3.7K0
Gizmos菜单_gi clamp
【100个 Unity实用技能】 | Scene视图选择对象是否边缘高亮、显示网格线
我们在Unity中的Scene界面选中某个游戏对象时,可以看到该对象会边缘发光,这其实是在Unity的界面默认设置的,我们可以手动开启和关闭。
呆呆敲代码的小Y
2023/03/09
1.1K0
【100个 Unity实用技能】 | Scene视图选择对象是否边缘高亮、显示网格线
点击加载更多

相似问题

在asp.net的网格视图中按Id隐藏列

30

查看id是否等于可见或隐藏

31

在具有链接按钮的网格视图中显示/隐藏网格视图

111

在网格视图中隐藏选择按钮

61

如何列出可见窗口及其ID?

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文