检查数组中的整数是连续还是按顺序
有没有什么最好的方法来检查数组中的元素是否连续顺序?检查数组中的整数是连续还是按顺序
如:
[1,2,3,4,5] // returns true
[1,2,4,3,5] // returns false
目前我实现什么是采取元素的差异,如果差异是1,那么我说,这是连续的顺序。
我正在寻找任何改进的方法。我想为Array
添加扩展名,但不知道如何实现。
鉴于你一个rray
let list = [1,2,3,4,5]
你可以使用一些函数式编程魔术
let consecutives = list.map { $0 - 1 }.dropFirst() == list.dropLast()
“目前我实现是采取元素的差异,如果 的差异是
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
}
}
如果这是一个一次性的问题,那么任何一个小的循环是好的,但它是一个探索通用解决方案有趣的问题。首先,我假定你的意思是每个元素必须比前一个元素大,而不仅仅是按顺序。
让我们建立一个通用的方法来回答“做这个集合中的所有元素都遵循一些规则。”首先,用一种通用的方式说“做所有事情”真的很不错。
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)
}
}
很好的答案。这将很快成为历史,但请注意,扩展不能编译Swift dfri
小备注:我会把'first(where:{!predicate($ 0)})== nil'写成'!contains(其中:{!predicate($ 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;
}
如果你*解释它,你的答案会更有帮助。顺便说一句,'isSeq([4,4,7,7],sequence:1)'return? –
你的意思是说,你想看看他们是按升序排序? – userx
只要做一个循环来检查下一个元素是否为当前元素+1 – litelite
'array == array.sorted()'? – Sulthan