Delphi 如何处理Zip算法的不匹配列表

Delphi 如何处理Zip算法的不匹配列表,delphi,functional-programming,algorithm,Delphi,Functional Programming,Algorithm,我正在考虑编写一个函数Zip例程的Delphi实现,它包含两个列表并输出一组元素对。因此,给它[1,2,3]和['a',b',c']喂食会得到[(1,'a'),(2,'b'),(3,'c')]作为结果。这是伟大的,如果两个输入是完全相同的长度,就像他们在每一个演示我看到这个功能在线。但是,如果第一个是[1,2,3,4]?输出应该是什么?在其他语言的其他实现中如何处理此情况?没有“正确”或“错误”的方法,具体实现细节取决于您。您可以采取以下几种方法: 1) 方法:抛出一个异常 2) Haskell

我正在考虑编写一个函数Zip例程的Delphi实现,它包含两个列表并输出一组元素对。因此,给它[1,2,3]和['a',b',c']喂食会得到[(1,'a'),(2,'b'),(3,'c')]作为结果。这是伟大的,如果两个输入是完全相同的长度,就像他们在每一个演示我看到这个功能在线。但是,如果第一个是[1,2,3,4]?输出应该是什么?在其他语言的其他实现中如何处理此情况?

没有“正确”或“错误”的方法,具体实现细节取决于您。您可以采取以下几种方法:

1) 方法:抛出一个异常

2) Haskell和Python方法:将输出截断为输入的最小长度

zip [1; 2; 3] ['a'; 'b'; 'c'; 'd'; 'e']
  = [ (1, 'a'); (2, 'b'); (3, 'c')]
截断有时很有用,这通常是压缩有限和无限序列时的情况

3) Ruby方法:零或零输出不可用值:

zip [1; 2; 3] ['a'; 'b'; 'c'; 'd'; 'e']
  = [ (1, 'a'); (2, 'b'); (3, 'c'); (nil, 'd'); (nil, 'e')]
4) 根据需要缩短元组2和元组1:

zip [1; 2; 3] ['a'; 'b'; 'c'; 'd'; 'e']
  = [ (1, 'a'); (2, 'b'); (3, 'c'); ('d'); ('e')]

我不知道有哪种语言能做到这一点。

Python会截断到最小序列的长度。这对我很有用。

一个常见的做法是用自己的尾巴来压缩列表。例如,将点列表转换为访问这些点的路径。尾部明显比列表短一个,但这肯定不是例外情况。另一个常见的方法是将一个列表及其所有尾部压缩,以获得一个可以从该列表中构造的无序对列表(以构造一个完整的图,例如:

liftM2 (=<<) zip tails

liftM2(=所以你的意思是不同的实现都有不同的实现方式。图…:(因此没有“错误”方法的原因;)在我看来,您可能可以通过消除过程缩小最佳实现的范围:抛出异常似乎是可以接受的。当您使用易于使用无限列表的语言时,静默截断列表是合适的,这似乎排除了Delphi。当您的语言不允许时,替换null值似乎是合适的将基本体视为int和bools,这与任何其他对象类型不同,这将再次排除Delphi。默认情况下,似乎最好抛出一个异常。如果您认为您可能希望支持传入一个充当惰性计算器的函数,请记住,在这种情况下,您只需截断,因为您无法事先知道如何使用它w很多元素都是可用的-因此如果这可能是相关的,您可能希望对“常规”也这样做压缩,以保持行为的一致性。但是,在处理闭包时,这可能更为相关——在我看来,它们比必须在某些类中声明变量并将其用于状态管理更好地支持惰性评估方法。正确的方法是#2。其他方法的类型不正确。抛出异常会更改函数的类型,使其为非总计(它并不总是返回列表)。这可能不是您想要的。返回null是欺骗。函数的类型表示,对于类型为
[a]
[b]
的列表,它将返回一个列表
[(a,b)]
。嗯,
null
既不属于
a
类型,也不属于
b
,因此您的类型将是谎言。这并不总是正确的。在Delphi中,nil(null)是指针类型,所有对象都是通过透明指针引用访问的。任何对象引用都可以为零,这是公认的事实,您的代码应该能够以某种方式将其作为有效值进行处理。(但如果您使用的是值类型而不是对象,则情况会变得更复杂。)
zip
截断,但您可以为
map
提供多个序列,并扩展为
None
;例如
map(tuplify[1,2,3],[4,5])==[(1,4)、(2,5)、(3,None)]
给定
def tuplify(*s):返回tuple(s)