在Swift中将对象数组按所有可能的顺序排序

3
想知道在Swift中是否有一种简洁的方法来做到这一点,可能使用一个或几个全局函数,如Map / Reduce等。
数组包含n个数量的唯一自定义对象。
例如,有3个项目。但可能更多或更少。[1,2,3]
将返回一个数组的数组
[ [1, 2, 3] [1, 3, 2] [2, 1, 3] [2, 3, 1] [3, 1, 2] [3, 2, 1] ]
这是在Java中完成任务的方法。只需要转换为Swift格式即可。
3个回答

2

https://gist.github.com/JadenGeller/5d49e46d4084fc493e72

他创建了结构体来处理排列:
var greetingPermutations = PermutationSequenceGenerator(elements: ["hi", "hey", "hello"])
while let greetingSequence = greetingPermutations.next(){
    for greeting in greetingSequence {
    print("\(greeting) ")
   }
   println()
}

或者:

var numberSpace = PermutationSpaceGenerator(objects: Array(1...4))
while let numberArray = numberSpace.next() {
   println(numberArray)
}

编辑:
这里是在 objc.io 上找到的更简单的方法。
添加扩展。
extension Array {
    var decompose : (head: T, tail: [T])? {
        return (count > 0) ? (self[0], Array(self[1..<count])) : nil 
    }
}

在你的扩展/类之外添加。
infix operator >>= {}
func >>=<A, B>(xs: [A], f: A -> [B]) -> [B] {
    return xs.map(f).reduce([], combine: +)
}

普通类函数
func between<T>(x: T, ys: [T]) -> [[T]] {
    if let (head, tail) = ys.decompose {
        return [[x] + ys] + between(x, ys: tail).map { [head] + $0 }
    } else {
        return [[x]]
    }
}


func permutations<T>(xs: [T]) -> [[T]] {
    if let (head, tail) = xs.decompose {
        return permutations(tail) >>= { permTail in
            self.between(head, ys: permTail)
        }
    } else {
        return [[]]
    }
}

测试

    let example = permutations([1,2,3,5,6,7,8])
    println(example)

这段代码扩展了 Array 的功能,添加了 decompose 函数和 >>== 运算符(用于扁平化)。关于扁平化的更多信息,请参见:http://www.objc.io/snippets/4.html

在编程中,“between(head, permTail)”的意思是什么? - DogCoffee
抱歉,忘记在函数之间粘贴。 - chrisamanse

2
也许有点像C语言,但这是一个已发布示例的替代方案。
var a = [1, 2, 3, 4, 5]
var b = [[Int]]()

func perms<T>(n: Int, inout a: [T], inout b: [[T]]) {
    if n == 0 {
        b.append(a)
    } else {
        for i in 0..<n {
            perms(n - 1, &a, &b)
            var j = 0
            if n % 2 == 0 {
                j = i
            }
            swap(&a[j], &a[n - 1])
        }
    }
}


perms(a.count, &a, &b)
println(b)

1

Swift 5

@DogCoffee的更新版本适用于Swift 5.x,全部都在一个数组扩展中:

extension Array {
    private var decompose : (head: Element, tail: [Element])? {
        return (count > 0) ? (self[0], Array(self[1..<count])) : nil
    }
    
    private func between<T>(x: T, ys: [T]) -> [[T]] {
        if let (head, tail) = ys.decompose {
            return [[x] + ys] + between(x: x, ys: tail).map { [head] + $0 }
        } else {
            return [[x]]
        }
    }
    
    private func permutations<T>(xs: [T]) -> [[T]] {
        if let (head, tail) = xs.decompose {
            return permutations(xs: tail) >>= { permTail in
                self.between(x: head, ys: permTail)
            }
        } else {
            return [[]]
        }
    }
    
    func allPermutations() -> [[Element]] {
        return permutations(xs: self)
    } 
}

infix operator >>=
func >>=<A, B>(xs: [A], f: (A) -> [B]) -> [B] {
    return xs.map(f).reduce([], +)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接