catpawsonkeyboard
catpawsonkeyboard

Reputation: 51

How to add values of two arrays that are different sizes in length?

If I have two int arrays such as

var array1 = [1,2,3]
var array2 = [1,2,3,5]

I'd like to be able to add the first element of the first array with the first element of the second array, and so on. However if an array has a different length than the other I'd like to keep the element that was not added in the return array. For this example my return array would be [2,4,6,5].

I tried using zip(array1,array2).map(+) but it would exclude the 5 from array2.

Upvotes: 3

Views: 813

Answers (5)

user652038
user652038

Reputation:

AnySequence(zip: (1...3, [1, 2, 3, 5])).map {
  Optional($0).map(+) ?? firstNonNil($0)!
}
public extension AnySequence {
  /// Like `zip`, but with `nil` elements for the shorter sequence after it is exhausted.
  init<Sequence0: Sequence, Sequence1: Sequence>(
    zip zipped: (Sequence0, Sequence1)
  ) where Element == (Sequence0.Element?, Sequence1.Element?) {
    self.init(
      sequence(
        state: (zipped.0.makeIterator(), zipped.1.makeIterator())
      ) { iterators in
        ((iterators.0.next(), iterators.1.next()) as Optional)
          .filter { $0 != nil || $1 != nil }
      }
    )
  }
}
public extension Optional {
  /// Exchange two optionals for a single optional tuple.
  /// - Returns: `nil` if either tuple element is `nil`.
  init<Wrapped0, Wrapped1>(_ optionals: (Wrapped0?, Wrapped1?))
  where Wrapped == (Wrapped0, Wrapped1) {
    switch optionals {
    case let (wrapped0?, wrapped1?):
      self = (wrapped0, wrapped1)
    default:
      self = nil
    }
  }
  
  /// Transform `.some` into `.none`, if a condition fails.
  /// - Parameters:
  ///   - isSome: The condition that will result in `nil`, when evaluated to `false`.
  func filter(_ isSome: (Wrapped) throws -> Bool) rethrows -> Self {
    try flatMap { try isSome($0) ? $0 : nil }
  }
}
public func firstNonNil<Element>(_ tuple: (Element?, Element?)) -> Element? {
  switch tuple {
  case (let _0?, _):
    return _0
  case (nil, let _1?):
    return _1
  case (nil, nil):
    return nil
  }
}

Upvotes: 0

Omar
Omar

Reputation: 51

//javaScript
var array1 = [1,2,3,4,5];
var array2 = [9,7,8,6,5,6,7];

let a= array1.length;
let b = array2.length;

var array3 = [];

let c = a>b?a:b;

for(let i=0; i<c; i++){
    if(i < a && i < b){
        array3.push(array1[i] + array2[i]);
    } else if(i >= a){
        array3.push(array2[i])
    } else{
        array3.push(array1[i])
    }
}

console.log(array3)

Upvotes: -1

impression7vx
impression7vx

Reputation: 1863

func combine2Arrays(array1:[Int], array2:[Int]) -> [Int] {
    var finalArray:[Int] = []
    let maxSize = max(array1.count, array2.count)
    
    for i in 0..<maxSize {
        let valToAdd1 = (array1.count > i ? array1[i] : 0)
        let valToAdd2 = (array2.count > i ? array2[i] : 0)
        let finalVal = valToAdd1 + valToAdd2
        finalArray.append(finalVal)
    }
    return finalArray
}

print(combine2Arrays(array1: [1,2,3], array2: [1,2,3,5]))

OR

func combine2Arrays(array1:[Int], array2:[Int]) -> [Int] {
    var finalArray:[Int] = zip(array1,array2).map(+)
    let largerArray = array1.count > array2.count ? array1 : array2
    let smallerArray = array1.count > array2.count ? array2 : array1
    let min = smallerArray.count
    let max = largerArray.count
    for i in min..<max {
        finalArray.append(largerArray[i])
    }
    return finalArray
}

print(combine2Arrays(array1: [1,2,3], array2: [1,2,3,5]))

Upvotes: -1

Artem Chernousov
Artem Chernousov

Reputation: 509

You can fill your smaller array with zeroes, then use zip. inout means that arrays are mutable, or you can make the copy of function parameters inside the function to make them mutable.

private func combineArrays(array1: inout [Int], array2: inout [Int]) -> [Int] {
    let maxSize = max(array1.count, array2.count)

    if (array1.count > array2.count) {
        array2.append(contentsOf: [Int](repeating: 0, count: maxSize - array2.count))
    } else if (array2.count > array1.count) {
        array1.append(contentsOf: [Int](repeating: 0, count: maxSize - array1.count))
    }

    return zip(array1, array2).map(+)
}

Upvotes: -1

Martin R
Martin R

Reputation: 539685

After adding the elements at the index positions which are common to both arrays (what you already did with zip and map) just append the remaining elements from both arrays (using append(contentsOf:) and dropFirst):

let array1 = [1, 2, 3]
let array2 = [1, 2, 3, 5]

var combined = zip(array1, array2).map(+)
let commonCount = combined.count
combined.append(contentsOf: array1.dropFirst(commonCount))
combined.append(contentsOf: array2.dropFirst(commonCount))

print(combined) // [2, 4, 6, 5]

Upvotes: 7

Related Questions