সুইফটে একটি অ্যারের অ্যারে সমতল করুন


143

flattenস্কেল, এক্সেন্ডেড, গ্রোভী, রুবি এবং কো- এ সুইফট টু- তে কোনও সমকক্ষ রয়েছে ?

var aofa = [[1,2,3],[4],[5,6,7,8,9]]
aofa.flatten() // shall deliver [1,2,3,4,5,6,7,8,9] 

অবশ্যই আমি এটির জন্য হ্রাস ব্যবহার করতে পারি তবে সেই ধরণের সফলতা পায়

var flattened = aofa.reduce(Int[]()){
    a,i in var b : Int[] = a
    b.extend(i)
    return b
}

এটি অ্যারের অবজেক্ট ব্যবহার করার মতো নয়?
ফাম হোয়ান

আমি এখনও সুইফটে নিজেই তাকাতে পারি নি তবে হাস্কেল এবং এফ # তে এটি একটি `কনক্যাট` - তাই সম্ভবত এর মতো কিছু দেখবেন? - আমি বরং ইতিবাচক যে এটি কোথাও আছে (বেশিরভাগ এফপি ল্যাংগুডগুলি mon মোন্ডাদের সম্পর্কে জানেন এবং এটি তালিকার বাঁধাই)
কার্স্টেন

হ্যাঁ হ্যাসেল এটিকে প্রকৃতপক্ষে বলা হয়।
ক্রিশ্চান ডায়েরিচ

আপনার andreschneider এর উত্তর গ্রহণ করা উচিত ।
রব

উত্তর:


436

সুইফট> = 3.0

reduce:

let numbers = [[1,2,3],[4],[5,6,7,8,9]]
let reduced = numbers.reduce([], +)

flatMap:

let numbers = [[1,2,3],[4],[5,6,7,8,9]]
let flattened = numbers.flatMap { $0 }

joined:

let numbers = [[1,2,3],[4],[5,6,7,8,9]]
let joined = Array(numbers.joined())

এখানে চিত্র বর্ণনা লিখুন


3
কেবল এটি আরও সাধারণভাবে জানাতে, flatMapসুইফট ১.২ হিসাবে উপলব্ধ।
মিক ম্যাককালাম

3
joined(আনুষ্ঠানিকভাবে পরিচিত flatten) এর মধ্যে পার্থক্য কী flatMap? এটি কি flatMapযোগদানের সময় এটি ম্যাপ / জিনিসকে রূপান্তর করতে পারে। তবে এখানে উদাহরণে আমাদের সত্যই দরকার নেই অর্থাৎ আমরা ফিরে আসি$0
হানি

6
@ ডিস্কি হয় 2D অ্যারে 1D অ্যারে সমতল flatMapকরবে বা মানগুলি সরিয়ে দেবে , দুটোই নয়। এটি নির্ধারণ করে যে 1 ম স্তরের অ্যারেগুলি যদি অ্যারে বা —চ্ছিক হয় তার ভিত্তিতে কোন করণীয় - সুতরাং আপনি যদি এটি 2D বিকল্পের বিকল্প (উদাহরণস্বরূপ ) পাস করেন তবে এটি এটি 1 ডি (উদাঃ ) এর সমতল করতে পছন্দ করবে । উভয়কে 1-ডি থেকে সমতল করতে এবং ২ য় স্তরের নীলগুলি সরিয়ে ফেলতে, আপনাকে করতে হবে । অন্য কথায়, মাত্রা-সমতলকরণ সমান এবং শূন্য-অপসারণ "সমতলকরণ" সমতুল্য । nilElement[[Int?]][Int?]array.flatMap { $0 }.flatMap { $0 }Array(array.joined())array.filter{ $0 != nil }.map{ $0! }
স্লিপ ডি। থম্পসন

1
প্রশ্নটিতে flatMapবর্ণিত ব্যবহারের জন্য @ ওয়ার্পলিং এখনও উপযুক্ত (একটি 2D অ্যারে 1D তে সমতল করা)। compactMapস্পষ্টভাবে nilএকটি ক্রম থেকে আইটেমগুলি সরিয়ে ফেলার জন্য , flatMapএকবার এর বৈকল্পিক হিসাবে ।
জিম ডোভে

1
নিবন্ধন করুন মুমাহাড্রেজাকোহকান এটি সঠিক। যেহেতু আপনার অ্যারে টাইপযুক্ত [[Any]], একটি flatMapসাধারণভাবে এটিকে কোনও ধরণের [Any]([1, 2, 3, 4, [5, 6], 7, 8, 9]) এ রূপান্তরিত করে । এবং যদি আমরা flatMapআবার আবেদন করি তবে আমরা একটি `কোনওতে অভিনয় করব? টাইপ করুন, যেখানে সংকলকটি আর জানবে না এটি যদি একটি সাধারণ মান বা একটি অ্যারে হয়।
andreschneider

31

সুইফট মান লাইব্রেরিতে আছে joinedসব ধরনের সঙ্গে মানানসই জন্য প্রয়োগ ফাংশন Sequence(অথবা প্রোটোকল flattenউপর SequenceType, যার মধ্যে সুইফট 3 আগে) Array:

let numbers = [[1,2,3],[4],[5,6,7,8,9]]
let flattened = Array(numbers.joined())

কিছু ক্ষেত্রে ব্যবহার joined()উপকারী হতে পারে কারণ এটি একটি নতুন অ্যারের পরিবর্তে অলস সংগ্রহ করে, তবে Array()উপরের উদাহরণের মতো ইনিশিয়ালাইজারে পাস করার সময় সর্বদা অ্যারেতে রূপান্তরিত হতে পারে ।


@ ক্রিসকো আপনি কীভাবে আমার উত্তরটি ভুল এবং "সরল সঠিক উত্তর" দেওয়ার মাপদণ্ডটি বিশদভাবে বর্ণনা করতে পারেন? আপনি কী দয়া করে এটিও বলতে পারেন যে কোনও উত্তর মুছে ফেলা কীভাবে কোনওভাবে প্রশ্নকে প্রভাবিত করতে পারে?
ম্যাক্স দেশিয়ভ

প্রথমে আপনার স্নিপেট চালানোর চেষ্টা করুন - আপনি কী ভাবেন এটি কি করে? এটা আসলে কী কাজ করে? মূল প্রশ্নটি কী ছিল? আপনার উত্তর সঠিক? যদি তা না হয় তবে এই পোস্টটির স্পষ্টতা উন্নত করতে এটি মুছে ফেলা ভাল। আমি নিজের ভুল উত্তর দিয়েও এটি করেছি।
ক্রিস কনভারটি

1
@ ক্রিসকো আপনার পরামর্শের জন্য আপনাকে অনেক ধন্যবাদ, তবে আমি কোথাও পোস্ট করার আগে স্নিপেটগুলি চালাই। আমার উত্তরটি সঠিক কারণ এটি ওপির অনুরোধের মতো ঠিক একই ফলাফল দেয় এবং এর জন্য কম কোড ব্যবহার করে। আমি স্বীকার করি যে আমার আসল উত্তরটি অ্যারের পরিবর্তে অলস সংগ্রহটি ফিরিয়ে দিচ্ছিল, যদিও তাতে প্রশ্নটিতে কোনও বিধিনিষেধ ছিল না। আমি এখনও মনে করি না যে একটি সঠিক উত্তর মুছে ফেলা কোনওভাবেই প্রশ্নের মান উন্নত করে।
ম্যাক্স দেশিয়েভ

এটা আমার বিন্দু ছিল - যে যখন পরীক্ষার / আউটপুট মুদ্রণ আপনি অ্যারে এর একটি অ্যারের পাবেন: FlattenBidirectionalCollection<Array<Array<Int>>>(_base: [[1, 2, 3], [4], [5, 6, 7, 8, 9]]))। আপনার বক্তব্যটি বৈধ যদিও আপনি এটি ফ্ল্যাট অ্যারের মতো অ্যাক্সেস করতে পারবেন তাই মনে হয় CustomStringConvertableবাস্তবায়ন বিভ্রান্তিকর। আপনার কোড স্নিপেট ছিল এবং এখনও একটি পরীক্ষা অনুপস্থিত।
ক্রিস কনভারের

1
দ্রুততম 3.0 হিসাবে, এর flatten()নতুন নামকরণ করা হয়েছেjoined()
মিস্টার এক্সকোডার

16

সুইফট 4.x / 5.x

অ্যারেতে আরও কিছুটা জটিলতা যুক্ত করার জন্য যদি অ্যারেটিতে অ্যারে থাকে তবে অ্যারেটি flatMapআসলে ব্যর্থ হয়।

ধরুন অ্যারে হয়

var array:[Any] = [1,2,[[3,4],[5,6,[7]]],8]

কি flatMapবা compactMapরিটার্নটি হ'ল:

array.compactMap({$0})

//Output
[1, 2, [[3, 4], [5, 6, [7]]], 8]

এই সমস্যাটি সমাধান করার জন্য, আমরা লুপ লজিক + পুনরাবৃত্তির জন্য আমাদের সাধারণটি ব্যবহার করতে পারি

func flattenedArray(array:[Any]) -> [Int] {
    var myArray = [Int]()
    for element in array {
        if let element = element as? Int {
            myArray.append(element)
        }
        if let element = element as? [Any] {
            let result = flattenedArray(array: element)
            for i in result {
                myArray.append(i)
            }

        }
    }
    return myArray
}

সুতরাং প্রদত্ত অ্যারে সহ এই ফাংশনটি কল করুন

flattenedArray(array: array)

ফলাফল হলো:

[1, 2, 3, 4, 5, 6, 7, 8]

এই ফাংশনটি অ্যারে যে কোন ধরণের চেপ্টা করতে সাহায্য করবে ক্ষেত্রে বিবেচনা করা Intএখানে

খেলার মাঠ আউটপুট: এখানে চিত্র বর্ণনা লিখুন




2

সুইফট 4.2

আমি নীচে একটি সাধারণ অ্যারে এক্সটেনশন লিখেছি। আপনি একটি অ্যারের সমতল করতে ব্যবহার করতে পারেন যাতে অন্য অ্যারে বা উপাদান থাকে। যোগদানের () পদ্ধতির বিপরীতে।

public extension Array {
    public func flatten() -> [Element] {
        return Array.flatten(0, self)
    }

    public static func flatten<Element>(_ index: Int, _ toFlat: [Element]) -> [Element] {
        guard index < toFlat.count else { return [] }

        var flatten: [Element] = []

        if let itemArr = toFlat[index] as? [Element] {
            flatten = flatten + itemArr.flatten()
        } else {
            flatten.append(toFlat[index])
        }

        return flatten + Array.flatten(index + 1, toFlat)
    }
}

ব্যবহার:

let numbers: [Any] = [1, [2, "3"], 4, ["5", 6, 7], "8", [9, 10]]

numbers.flatten()

1

এর আরও একটি জেনেরিক বাস্তবায়ন reduce,

let numbers = [[1,2,3],[4],[5,6,7,8,9]]
let reduced = reduce(numbers,[],+)

এটি একই জিনিসটি সম্পাদন করে তবে কী চলছে তাতে আরও অন্তর্দৃষ্টি দিতে পারে reduce

অ্যাপলের ডক্স থেকে,

func reduce<S : SequenceType, U>(sequence: S, initial: U, combine: (U, S.Generator.Element) -> U) -> U

বিবরণ

ঘন ঘন কল করার ফলাফলটি প্রাথমিকভাবে আরম্ভিক প্রতিটি ক্রমের প্রতিটি উপাদানকে আরম্ভ করে একত্রিত মানের সাথে সংযুক্ত করে ফিরে আসে।


আপনার কোড সহ আমি পেয়েছি:Use of unresolved identifier 'reduce'
জেসন মুর

1

@ রহমিবোজড্যাগের উত্তরটি পরিবর্তিত হয়েছে, ১. জনসাধারণের এক্সটেনশনের পদ্ধতিগুলি সর্বজনীন। ২. অতিরিক্ত পদ্ধতি সরানো হয়েছে, সূচনা সূচি সর্বদা শূন্য থাকবে। ৩. আমি শূন্য এবং বিকল্পগুলির জন্য কমপ্যাক্টম্যাপের ভিতরে রাখার কোনও উপায় খুঁজে পাইনি কারণ অভ্যন্তরীণ পদ্ধতি টি সর্বদা [কোনও?] থাকে, কোনও পরামর্শ স্বাগত।

 let array = [[[1, 2, 3], 4], 5, [6, [9], 10], 11, nil] as [Any?]

 public extension Array {

 func flatten<T>(_ index: Int = 0) -> [T] {
        guard index < self.count else { 
            return [] 
        }

        var flatten: [T] = []

        if let itemArr = self[index] as? [T] {
            flatten += itemArr.flatten()
        } else if let element = self[index] as? T {
            flatten.append(element)
        }
        return flatten + self.flatten(index + 1)
   }

}

let result: [Any] = array.flatten().compactMap { $0 }
print(result)
//[1, 2, 3, 4, 5, 6, 9, 10, 11]

0

আপনি নীচের পদ্ধতিটি ব্যবহার করে নেস্টেড অ্যারে সমতল করতে পারেন:

var arrays = [1, 2, 3, 4, 5, [12, 22, 32], [[1, 2, 3], 1, 3, 4, [[[777, 888, 8999]]]]] as [Any]

func flatten(_ array: [Any]) -> [Any] {

    return array.reduce([Any]()) { result, current in
        switch current {
        case(let arrayOfAny as [Any]):
            return result + flatten(arrayOfAny)
        default:
            return result + [current]
        }
    }
}

let result = flatten(arrays)

print(result)

/// [1, 2, 3, 4, 5, 12, 22, 32, 1, 2, 3, 1, 3, 4, 777, 888, 8999]

0

অ্যাপল সুইফ্ট সংস্করণ 5.1.2 (swiftlang-1100.0.278 ঝনঝন -1100.0.33.9)
লক্ষ্য: x86_64-আপেল-ডারউইন 19.2.0

স্ক্রিনশট

let optionalNumbers = [[1, 2, 3, nil], nil, [4], [5, 6, 7, 8, 9]]
print(optionalNumbers.compactMap { $0 }) // [[Optional(1), Optional(2), Optional(3), nil], [Optional(4)], [Optional(5), Optional(6), Optional(7), Optional(8), Optional(9)]]
print(optionalNumbers.compactMap { $0 }.reduce([], +).map { $0 as? Int ?? nil }.compactMap{ $0 }) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(optionalNumbers.compactMap { $0 }.flatMap { $0 }.map { $0 as? Int ?? nil }.compactMap{ $0 }) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(Array(optionalNumbers.compactMap { $0 }.joined()).map { $0 as? Int ?? nil }.compactMap{ $0 }) // [1, 2, 3, 4, 5, 6, 7, 8, 9]

let nonOptionalNumbers = [[1, 2, 3], [4], [5, 6, 7, 8, 9]]
print(nonOptionalNumbers.compactMap { $0 }) // [[1, 2, 3], [4], [5, 6, 7, 8, 9]]
print(nonOptionalNumbers.reduce([], +)) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(nonOptionalNumbers.flatMap { $0 }) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(Array(nonOptionalNumbers.joined())) // [1, 2, 3, 4, 5, 6, 7, 8, 9]

0

সুইফট 5.1

public extension Array where Element: Collection {

    func flatten() -> [Element.Element] {
        return reduce([], +)
    }
}

আপনি যদি অভিধানের মানগুলির জন্য এটিও চান তবে:

public extension Dictionary.Values where Value : Collection {
    func flatten() -> [Value.Element]{
         return self.reduce([], +)
    }
}


-1

ম্যাট্রিক্স হল [[আমারডিটিও]]?

সুইফ্ট ৫-এ আপনি এই = অ্যারে ব্যবহার করতে পারেন (স্ব.ম্যাট্রিক্স!। জয়েন্টেড ())


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.