2017-08-02 60 views
2

有没有什么最好的方法来检查数组中的元素是否连续顺序?检查数组中的整数是连续还是按顺序

如:

[1,2,3,4,5] // returns true 
[1,2,4,3,5] // returns false 

目前我实现什么是采取元素的差异,如果差异是1,那么我说,这是连续的顺序。

我正在寻找任何改进的方法。我想为Array添加扩展名,但不知道如何实现。

+0

你的意思是说,你想看看他们是按升序排序? – userx

+0

只要做一个循环来检查下一个元素是否为当前元素+1 – litelite

+0

'array == array.sorted()'? – Sulthan

回答

4

鉴于你一个rray

let list = [1,2,3,4,5] 

你可以使用一些函数式编程魔术

let consecutives = list.map { $0 - 1 }.dropFirst() == list.dropLast() 
1

“目前我实现是采取元素的差异,如果 的差异是1然后我说这是按顺序排列。”

基于以上的说法,看来你想,对一个整数数组,看是否所有的成员都是连续

您已经描述了此算法的逻辑:您可以实现它,例如使用for ... in ... where循环,只有在where子句标识两个连续顺序不连续的元素时才会输入该正文。例如:

extension Array where Element == Int { 
    func numbersAreConsecutive() -> Bool { 
     for (num, nextNum) in zip(self, dropFirst()) 
      where (nextNum - num) != 1 { return false } 
     return true 
    } 
} 

var arr = [1, 2, 3, 4, 5] 
print(arr.numbersAreConsecutive()) // true 

arr = [1, 2, 4, 5] 
print(arr.numbersAreConsecutive()) // false 

arr = [1] 
print(arr.numbersAreConsecutive()) // true 

arr = [] 
print(arr.numbersAreConsecutive()) // true 

arr = [2, 1] 
print(arr.numbersAreConsecutive()) // false 

延伸的延伸,以符合Integer所有类型:

extension Array where Element: Integer { 
    func numbersAreConsecutive() -> Bool { 
     for (num, nextNum) in zip(self, dropFirst()) 
      where (nextNum - num) != 1 { return false } 
     return true 
    } 
} 
2

如果这是一个一次性的问题,那么任何一个小的循环是好的,但它是一个探索通用解决方案有趣的问题。首先,我假定你的意思是每个元素必须比前一个元素大,而不仅仅是按顺序。

让我们建立一个通用的方法来回答“做这个集合中的所有元素都遵循一些规则。”首先,用一种通用的方式说“做所有事情”真的很不错。

extension Sequence { 
    func all(pass predicate: (Element) -> Bool) -> Bool { 
     // If nothing is false, everything is true 
     return !self.contains(where: { !predicate($0) }) 
    } 
} 

这将返回序列中的所有元素是否服从某个规则。

现在我们可以提出这样的问题:做一个集合的所有成对要素遵循一定的规则:

extension Collection { 
    func passesForConsecutiveValues(_ predicate:(Element, Element) -> Bool) -> Bool { 
     return zip(self, dropFirst()).all(pass: predicate) 
    } 
} 

zip(x, x.dropFirst()只是创建“成对元素”,然后我们问:“这样做,他们都满足我们的规则?“例如:

// Are all elements one more than their predecessor? 
[1,2,4,5].passesForConsecutiveValues { $1 == $0 + 1 } // true 

现在您可能已经注意到,我在中间从序列切换到集合。为什么?因为zip(x, x.dropFirst())未在任意序列上定义。您只能被允许迭代一次序列。不幸的是,没有办法知道;它在文档中被认为是“关于序列的特殊知识”。的Bleh。我想念Scala的TraversableOnce vs. Sequence,将需求转移到类型中。

也就是说,我们绝对可以为Sequence创建这个。我们只需要建立zip(x, x.dropFirst())的替代品。我们叫它pairwise,它会返回一个迭代:如果序列原本预期

extension Sequence { 
    func passesForConsecutiveValues(_ predicate:(Element, Element) -> Bool) -> Bool { 
     return pairwise().all(pass: predicate) 
    } 
} 
+0

很好的答案。这将很快成为历史,但请注意,扩展不能编译Swift <4(需要'Iterator.Element'而不是'Element'等等)。另外,你可以在'all(...)'方法中为'first(...)'调用省略'self',就像我们为'dropFirst(...)'调用完成的一样。 – dfri

+1

小备注:我会把'first(where:{!predicate($ 0)})== nil'写成'!contains(其中:{!predicate($ 0)})' - 但这可能是个人偏好的问题。 –

+0

是的;那更好。谢谢。 –

0

它将返回真:

extension Sequence { 
    func pairwise() -> AnyIterator<(Element, Element)> { 
     var it = makeIterator() 
     guard var last_value = it.next() else { return AnyIterator{ return nil } } 

     return AnyIterator { 
      guard let value = it.next() else { return nil } 
      defer { last_value = value } 
      return (last_value, value) 
     } 
    } 
} 

有了这样的,我们可以在序列建立这个它会返回错误

它有两个检查

1.Checking whether the array is sequence(Find the array is sequence) 

    1.1 Sortedarray[0] + arraycount multiple with sequence (1,2,3, etc) and minus the sequence. 
    1.2 compare the above calculated value with last value of sorted array. if it matche we could consider The array is sequence. 

2. Compare the source array and sorted array to confirm it is in order 


isSeq([4,5,6,7],sequence:1) **return True** 
isSeq([100,102,104,106,108],sequence:2) **return True** 
    isSeq([100,103,106,109,110],sequence:3) **return false** 

    func isSeq(_ arrayValue:[Int],sequence:Int) ->Bool{ 

     let sortedValue = arrayValue.sorted() 

     if(sortedValue[0] + (sortedValue.count * sequence) - sequence == sortedValue[sortedValue.count - 1]){ 
      if(arrayValue == sortedValue){ 
       return true 
      } 
     } 

     return false; 
    } 
+0

如果你*解释它,你的答案会更有帮助。顺便说一句,'isSeq([4,4,7,7],sequence:1)'return? –

相关问题