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ę?

Troja
źródło
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:"-")
Antonio
źródło
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"
Imanou Petit
źródło
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
}
Siva
źródło
23

Szybki 3

["I Love","Swift"].joined(separator:" ") // previously joinWithSeparator(" ")
hardikdevios
źródło
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: " ")
Anargit garg
źródło
11

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

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

W duchu programowania funkcjonalnego 🤖

eonista
źródło
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.

Agent Smith
źródło
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"
Onur Var
źródło
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(",")
Carlos Perez Perez
źródło
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: "-")
Sourav Chandra
źródło
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

Maninderjit Singh
źródło
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ęć.

Rob Napier
źródło
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]"
123FLO321
źródło
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
        }
    }
}
Bartłomiej Semańczyk
źródło
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!)
Alexey Chekanov
źródło
0

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

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

da ci wartość ciągu

Oshitha Wimalasuriya
źródło
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;
    }
}
jan07
źródło
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: ",")
Tej Patel
źródło
-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
    }
}
Ty Daniels
źródło
-1

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

String(tobeFormattedString)

dheeru
źródło
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,