1

help me find an array in the array. In this implementation, I return the entire array.

[(name: "Bell 2", arr: [arrSub(sub_txt: "Test 2, 1"),arrSub(sub_txt: "Test 2, 2")])]

I need to return:

[(name: "Bell 2", arr: [arrSub(sub_txt: "Test 2, 2")])]

// Playground

import UIKit

struct arrSub {
    let sub_txt: String
}

struct test {
    let name: String
    let arr: [arrSub]

    init(name: String, arr: [arrSub]) {
        self.name = name
        self.arr  = arr
    }
}

var testArr = [test]()

testArr.append(test(name: "Line 1", arr: [arrSub(sub_txt: "Line 1, 1"), arrSub(sub_txt: "Line 1, 2")]))
testArr.append(test(name: "Bell 2", arr: [arrSub(sub_txt: "Bell 2, 1"), arrSub(sub_txt: "Bell 2, 2")]))
testArr.append(test(name: "Bell 2", arr: [arrSub(sub_txt: "Test 2, 1"), arrSub(sub_txt: "Test 2, 2")]))

let new = testArr.filter({
    $0.arr.contains(where: { $0.sub_txt.contains("Test 2, 2") } )        
})

print(new)

3 Answers 3

2

A simple filter won't help you achieve your goals, since you are trying to modify the test instances as well by filtering their arr property. You can use compactMap instead of filter to return modified test instances in case they fulfilled the filter criterion or nil if they didn't and compactMap will only keep the non-nil values.

let new = testArr.compactMap({ test->Test? in
let foundArrSub = test.arr.filter({ $0.sub_txt.contains("Test 2, 2") })
    if foundArrSub.count > 0 {
        return Test(name: test.name, arr: foundArrSub)
    }
    return nil
})

Test data:

var testArr = [Test]()

testArr.append(Test(name: "Line 1", arr: [ArrSub(sub_txt: "Line 1, 1"), ArrSub(sub_txt: "Line 1, 2")]))
testArr.append(Test(name: "Bell 2", arr: [ArrSub(sub_txt: "Bell 2, 1"), ArrSub(sub_txt: "Bell 2, 2")]))
testArr.append(Test(name: "Bell 2", arr: [ArrSub(sub_txt: "Test 2, 1"), ArrSub(sub_txt: "Test 2, 2"),ArrSub(sub_txt: "Test 2, 23")]))

[__lldb_expr_1.Test(name: "Bell 2", arr: [__lldb_expr_1.ArrSub(sub_txt: "Test 2, 2"), __lldb_expr_1.ArrSub(sub_txt: "Test 2, 23")])]

You should conform to the Swift naming convention, which is UpperCamelCase for types, so I changed test to Test and arrSub to ArrSub.

Sign up to request clarification or add additional context in comments.

1 Comment

This search will find only one record always in the substructure. But I need to return all the elements that are equal to the search condition.
0

Thanks, @Dávid Pásztor. I just slightly corrected

let new = testArr.compactMap { (myTest) -> test? in
if let foundArrSub = myTest.arr.first(where: { $0.sub_txt.contains("Test 2, 2") }){
    return test(name: myTest.name, arr: [foundArrSub])
}
return nil} 

This search will find only one record always in the substructure. But I need to return all the elements that are equal to the search condition.

Comments

0

You can use reduce also

let news =  testArr.reduce([test]()) { (result, testObj) -> [test] in

            let internalArray  = testObj.arr.filter({ (arraySub) -> Bool in
                return   arraySub.sub_txt.range(of:"Test 2, 2") != nil
            }).filter({ (arraySub) -> Bool in
                return   arraySub.sub_txt.range(of:"Test 2, 2") != nil
            })
        if internalArray.count > 0 {
            return result + [test.init(name: testObj.name, arr: internalArray)]
        }else{
            return result
        }
    }

    print(news)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.