Jak przekonwertować szybką tablicę na ciąg?


353

Wiem, jak to zrobić programowo, ale jestem pewien, że istnieje wbudowany sposób ...

Każdy język, którego użyłem, ma domyślną reprezentację tekstową dla kolekcji obiektów, którą wypluje, gdy spróbujesz połączyć tablicę z łańcuchem lub przekazać ją do funkcji print () itp. Czy język Apple jest szybki masz wbudowany sposób łatwego przekształcania tablicy w ciąg znaków, czy też zawsze musimy jawnie określać tablicę?


3
Swift 4: array.description lub jeśli chcesz niestandardowy separatorarray.joined(separator: ",")
Jonathan Solorzano

Odpowiedzi:


697

Jeśli tablica zawiera ciągi, można korzystać z String„s joinmetody:

var array = ["1", "2", "3"]

let stringRepresentation = "-".join(array) // "1-2-3"

W Swift 2 :

var array = ["1", "2", "3"]

let stringRepresentation = array.joinWithSeparator("-") // "1-2-3"

Może to być przydatne, jeśli chcesz użyć określonego separatora (myślnik, spacja, przecinek itp.).

W przeciwnym razie możesz po prostu użyć descriptionwłaściwości, która zwraca ciąg znaków reprezentujący tablicę:

let stringRepresentation = [1, 2, 3].description // "[1, 2, 3]"

Wskazówka: każdy obiekt implementujący Printableprotokół ma descriptionwłaściwość. Jeśli zastosujesz ten protokół we własnych klasach / strukturach, uczynisz je również przyjaznymi do drukowania

W Swift 3

  • joinstaje się joinedprzykładem[nil, "1", "2"].flatMap({$0}).joined()
  • joinWithSeparatorstaje się joined(separator:)(dostępne tylko dla Array of Strings)

W Swift 4

var array = ["1", "2", "3"]
array.joined(separator:"-")

2
@Andrej: Działa zarówno w wersji 1.2, jak i 2.0. Czy używasz tablicy ciągów?
Antonio

1
Antonio, przepraszam, mój zły. Miałem problem z moją tablicą. Teraz mogę potwierdzić, że twoje rozwiązanie działa. :)
Andrej,

12
"-".join(array)nie jest już dostępny w Swift 2, Xcode 7 Beta 6, spróbuj użyćarray.joinWithSeparator("-")
Harry Ng

87
joinWithSeparatorjest dostępna tylko dla tablicy ciągów. Jeśli masz tablicę innych obiektów, użyj mapnajpierw. Na przykład[1, 2, 3].map({"\($0)"}).joinWithSeparator(",")
Dmitry

3
@Dmitry Nie używaj wyłącznie interpolacji ciągów do konwersji na ciąg. O wiele fajniej jest użyć inicjatora na String
Alexander - Przywróć Monikę

130

W Swift 5, w zależności od potrzeb, możesz wybrać jeden z poniższych przykładowych kodów Placu Zabaw, aby rozwiązać problem.


Przekształcanie tablicy Characters w Stringseparator bez:

let characterArray: [Character] = ["J", "o", "h", "n"]
let string = String(characterArray)

print(string)
// prints "John"

Przekształcanie tablicy Strings w Stringseparator bez:

let stringArray = ["Bob", "Dan", "Bryan"]
let string = stringArray.joined(separator: "")

print(string) // prints: "BobDanBryan"

Przekształcanie tablicy Strings w Stringseparator między słowami:

let stringArray = ["Bob", "Dan", "Bryan"]
let string = stringArray.joined(separator: " ")

print(string) // prints: "Bob Dan Bryan"

Przekształcanie tablicy Strings w Stringseparator między znakami:

let stringArray = ["car", "bike", "boat"]
let characterArray = stringArray.flatMap { $0 }
let stringArray2 = characterArray.map { String($0) }
let string = stringArray2.joined(separator: ", ")

print(string) // prints: "c, a, r, b, i, k, e, b, o, a, t"

Przekształcanie tablicy Floats w Stringseparator między liczbami:

let floatArray = [12, 14.6, 35]
let stringArray = floatArray.map { String($0) }
let string = stringArray.joined(separator: "-")

print(string)
// prints "12.0-14.6-35.0"

Mam ciąg, który wygląda następująco: „[1,2,3]”. Czy jest jakiś sposób, aby łatwo przekonwertować to na tablicę [Int]? łatwo tj. odwrotność tego, co robi .description?
user2363025

@ user2363025 uni może korzystać z dekodera JSON. try JSONDecoder().decode([Int].self, from: Data(string.utf8))
Leo Dabus

48

Swift 2.0 Xcode 7.0 beta 6 i nowsze zastosowania joinWithSeparator()zamiast join():

var array = ["1", "2", "3"]
let stringRepresentation = array.joinWithSeparator("-") // "1-2-3"

joinWithSeparator jest zdefiniowany jako rozszerzenie na SequenceType

extension SequenceType where Generator.Element == String {
    /// Interpose the `separator` between elements of `self`, then concatenate
    /// the result.  For example:
    ///
    ///     ["foo", "bar", "baz"].joinWithSeparator("-|-") // "foo-|-bar-|-baz"
    @warn_unused_result
    public func joinWithSeparator(separator: String) -> String
}

23

Szybki 3

["I Love","Swift"].joined(separator:" ") // previously joinWithSeparator(" ")

1
Powiedziałbym, że jest to [„I Love”, „Swift”]. Dołączył (separator: „”)
Loebre

15

W Swift 4

let array:[String] = ["Apple", "Pear ","Orange"]

array.joined(separator: " ")

11

Ponieważ nikt nie wspomniał o zmniejszeniu, oto on:

[0, 1, 1, 0].map {"\($0)"}.reduce("") {$0 + $1 } // "0110"

W duchu programowania funkcjonalnego 🤖


3
Dobry sposób robienia rzeczy, dzięki ... dodanie krótszym końcu linii poleceń: [0,1,1,0].map{"\($0)"}.reduce("",+). 😉
XLE_22,

@ XLE_22[0,1,1,0].map(String.init).joined()
Leo Dabus

8

Aby zmienić tablicę ciągów opcjonalnych / nie opcjonalnych

//Array of optional Strings
let array : [String?] = ["1",nil,"2","3","4"]

//Separator String
let separator = ","

//flatMap skips the nil values and then joined combines the non nil elements with the separator
let joinedString = array.flatMap{ $0 }.joined(separator: separator)


//Use Compact map in case of **Swift 4**
    let joinedString = array.compactMap{ $0 }.joined(separator: separator

print(joinedString)

Tutaj flatMap , compactMap pomija wartości zero w tablicy i dołącza inne wartości, aby dać połączony ciąg.


3
@YashBedi W Swift 4 używamy compactMap zamiast flatMap
Agent Smith

jakie znaczenie ma „$”?
Augusto

2
@Augusto Swift automatycznie podaje skrócone nazwy argumentów do wbudowanych zamknięć, które mogą być używane do odwoływania się do wartości argumentów zamknięcia o nazwach $ 0, 1 $, 2 $. Tutaj 0 $ odnosi się do pierwszych argumentów String zamknięcia.
Agent Smith,

4

Mój działa na NSMutableArray ze składnikamiJoinedByString

var array = ["1", "2", "3"]
let stringRepresentation = array.componentsJoinedByString("-") // "1-2-3"

4

W Swift 2.2 może być konieczne rzutowanie tablicy na NSArray, aby użyć składnikówJoinedByString („,”)

let stringWithCommas = (yourArray as NSArray).componentsJoinedByString(",")

Nawiasem mówiąc, jest to tylko szybkie tłumaczenie celu-c.
Muhammad Zeeshan,

3

Jeśli chcesz porzucić puste ciągi w tablicy.

["Jet", "Fire"].filter { !$0.isEmpty }.joined(separator: "-")

Jeśli chcesz również filtrować wartości zerowe:

["Jet", nil, "", "Fire"].flatMap { $0 }.filter { !$0.isEmpty }.joined(separator: "-")

1
bardzo elegancki, dziękuję :)
CheshireKat

2
let arrayTemp :[String] = ["Mani","Singh","iOS Developer"]
    let stringAfterCombining = arrayTemp.componentsJoinedByString(" ")
   print("Result will be >>>  \(stringAfterCombining)")

Rezultatem będzie >>> Mani Singh iOS Developer


1

Szybkim odpowiednikiem tego, co opisujesz, jest interpolacja ciągów. Jeśli myślisz o takich rzeczach jak JavaScript "x" + array, odpowiednikiem Swift jest"x\(array)" .

Ogólnie rzecz biorąc, istnieje istotna różnica między interpolacją łańcuchów a Printableprotokołem. Tylko niektóre klasy są zgodne Printable. Każda klasa może być w jakiś sposób interpolowana przez łańcuch. Jest to pomocne podczas pisania ogólnych funkcji. Nie musisz ograniczać się do Printablezajęć.


1

Możesz wydrukować dowolny obiekt za pomocą funkcji drukowania

lub użyj \(name)do konwersji dowolnego obiektu na ciąg.

Przykład:

let array = [1,2,3,4]

print(array) // prints "[1,2,3,4]"

let string = "\(array)" // string == "[1,2,3,4]"
print(string) // prints "[1,2,3,4]"

1

Utwórz rozszerzenie dla Array:

extension Array {

    var string: String? {

        do {

            let data = try JSONSerialization.data(withJSONObject: self, options: [.prettyPrinted])

            return String(data: data, encoding: .utf8)

        } catch {

            return nil
        }
    }
}

0

Separator może być złym pomysłem w przypadku niektórych języków, takich jak hebrajski lub japoński. Spróbuj tego:

// Array of Strings
let array: [String] = ["red", "green", "blue"]
let arrayAsString: String = array.description
let stringAsData = arrayAsString.data(using: String.Encoding.utf16)
let arrayBack: [String] = try! JSONDecoder().decode([String].self, from: stringAsData!)

Odpowiednio dla innych typów danych:

// Set of Doubles
let set: Set<Double> = [1, 2.0, 3]
let setAsString: String = set.description
let setStringAsData = setAsString.data(using: String.Encoding.utf16)
let setBack: Set<Double> = try! JSONDecoder().decode(Set<Double>.self, from: setStringAsData!)

0

jeśli masz listę tablic łańcuchowych, przekonwertuj na Int

let arrayList = list.map { Int($0)!} 
     arrayList.description

da ci wartość ciągu


0

dla dowolnego typu elementu

extension Array {

    func joined(glue:()->Element)->[Element]{
        var result:[Element] = [];
        result.reserveCapacity(count * 2);
        let last = count - 1;
        for (ix,item) in enumerated() {
            result.append(item);
            guard ix < last else{ continue }
            result.append(glue());
        }
        return result;
    }
}

0

Spróbuj tego:

let categories = dictData?.value(forKeyPath: "listing_subcategories_id") as! NSMutableArray
                        let tempArray = NSMutableArray()
                        for dc in categories
                        {
                            let dictD = dc as? NSMutableDictionary
                            tempArray.add(dictD?.object(forKey: "subcategories_name") as! String)
                        }
                        let joinedString = tempArray.componentsJoined(by: ",")

-1

DLA SWIFT 3:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    if textField == phoneField
    {
        let newString = NSString(string: textField.text!).replacingCharacters(in: range, with: string)
        let components = newString.components(separatedBy: NSCharacterSet.decimalDigits.inverted)

        let decimalString = NSString(string: components.joined(separator: ""))
        let length = decimalString.length
        let hasLeadingOne = length > 0 && decimalString.character(at: 0) == (1 as unichar)

        if length == 0 || (length > 10 && !hasLeadingOne) || length > 11
        {
            let newLength = NSString(string: textField.text!).length + (string as NSString).length - range.length as Int

            return (newLength > 10) ? false : true
        }
        var index = 0 as Int
        let formattedString = NSMutableString()

        if hasLeadingOne
        {
            formattedString.append("1 ")
            index += 1
        }
        if (length - index) > 3
        {
            let areaCode = decimalString.substring(with: NSMakeRange(index, 3))
            formattedString.appendFormat("(%@)", areaCode)
            index += 3
        }
        if length - index > 3
        {
            let prefix = decimalString.substring(with: NSMakeRange(index, 3))
            formattedString.appendFormat("%@-", prefix)
            index += 3
        }

        let remainder = decimalString.substring(from: index)
        formattedString.append(remainder)
        textField.text = formattedString as String
        return false
    }
    else
    {
        return true
    }
}

-1

Jeśli pytasz, to coś takiego: tobeFormattedString = ["a", "b", "c"] Output = "abc"

String(tobeFormattedString)


Nie, to nie działa. Stringnie ma inicjatora zdolnego do tego. Albo korzystasz z niestandardowego rozszerzenia lub biblioteki innej firmy, albo po prostu się mylisz.
Eric Aya,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.