Related
I have an array of arrays of Int and I want to sum every value within all the values in the same position in a performing way. For example:
let array: [[Int]] = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
The result should be:
let result: [Int] = [11, 14, 11, 9]
If this is too complex, I can make all subarrays to have the same amount of elements.
My current soultion is the following but I believe it has to be a cleaner and more efficient way of doing it:
func sumElementsInSubArrays(_ array: [[Int]]) -> [Int] {
var result: [Int] = []
for subarray in array {
for (i, value) in subarray.enumerated() {
if result.count > (i) {
result[i] = result[i] + value
} else {
result[i] = value
}
}
}
return result
}
There may be several ways like HOF to deal with this situation but if you are new to it like me , you can do it like this :
Considering all the subArrays to have same number of element :
let array = [[1, 2, 3, 4], [5, 2, 7, 0] , [1, 7, 9, 4]]
var finalArray = [Int]()
for i in 0..<(array.first?.count ?? 0) {
var aElement = 0
array.forEach { aArray in
aElement += aArray[i]
}
finalArray.append(aElement)
}
//Final array should look like this at this point : [7, 11, 19, 8]
You could use a couple of nested loops (I don't think performance wise using reduce would be faster, thought it may look better/debatably be better for readability):
func sumElementsInSubArrays(_ array: [[Int]]) -> [Int] {
var result: [Int] = []
for subarray in array {
for (i, value) in subarray.enumerated() {
if result.count > i {
result[i] += value
} else {
result.append(value)
}
}
}
return result
}
print(sumElementsInSubArrays([[1, 2, 3], [4, 5], [6, 7, 8, 9]]))
print(sumElementsInSubArrays([]))
print(sumElementsInSubArrays([[]]))
Output:
[11, 14, 11, 9]
[]
[]
This question already has answers here:
iOS swift remove elements of an array from another array
(9 answers)
Closed 5 years ago.
Array1 = [1, 2, 3, 4, 5, 6]
Array2 = [1,5]
I want to get:
Array1 = [2, 3, 4, 6]
I want to do this by using Set because these arrays may get larger.
Also it is important that I maintain the order of the array.
Create a set with all elements from the second array,
then filter the first array to get only the elements which are not
in the set:
let array1 = [5, 4, 1, 2, 3, 4, 1, 2]
let array2 = [1, 5]
let set2 = Set(array2)
let result = array1.filter { !set2.contains($0) }
print(result) // [4, 2, 3, 4, 2]
This preserves the order (and duplicate elements) from the first
array. Using a set is advantageous if the second array can be large,
because the lookup is faster.
var array1 = [1, 2, 3, 4, 5, 6]
var array2 = [1,5]
var arrayResult = array1.enumerated()
.filter { !array2.contains($0.0 + 1) }
.map { $0.1 }
print(arrayResult)
[2, 3, 4, 6]
Another ways to achieve the same result:
1. User filter
let arrayResult = array1.filter { element in
return !array2.contains(element)
}
2. Use Sort
array2.sorted(by: >).forEach { if $0 < self.array1.count { self.array1.remove(at: $0) } }
Remove elements using indexes array:
Array of Strings and indexes
let animals = ["cats", "dogs", "chimps", "moose", "squarrel", "cow"]
let indexAnimals = [0, 3, 4]
let arrayRemainingAnimals = animals
.enumerated()
.filter { !indexAnimals.contains($0.offset) }
.map { $0.element }
print(arrayRemainingAnimals)
//result - ["dogs", "chimps", "cow"]
Array of Integers and indexes
var numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
let indexesToRemove = [3, 5, 8, 12]
numbers = numbers
.enumerated()
.filter { !indexesToRemove.contains($0.offset) }
.map { $0.element }
print(numbers)
//result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
Remove elements using element value of another array
Arrays of integers
let arrayResult = numbers.filter { element in
return !indexesToRemove.contains(element)
}
print(arrayResult)
//result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
Arrays of strings
let arrayLetters = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
let arrayRemoveLetters = ["a", "e", "g", "h"]
let arrayRemainingLetters = arrayLetters.filter {
!arrayRemoveLetters.contains($0)
}
print(arrayRemainingLetters)
//result - ["b", "c", "d", "f", "i"]
Use the filter function
let result = Array1.filter { element in
return !Array2.contains(element)
}
(Note: because you added to your question and maintaining order then my answer is not right anymore, because Set don't preserve the order. then the filter answers are a better fit)
use subtracting from a Set:
array1 = Array(Set(array1).subtracting(Set(array2)))
you can add this as an operator :
Using the Array → Set → Array method mentioned by Antonio, and with the convenience of an operator, as freytag pointed out, I've been very satisfied using this:
// Swift 3.x
func - <Element: Hashable>(lhs: [Element], rhs: [Element]) -> [Element]
{
return Array(Set<Element>(lhs).subtracting(Set<Element>(rhs)))
}
quoted from: https://stackoverflow.com/a/42679608/1930509
let array1 = [1, 2, 3, 4, 5, 6]
let array2 = [1,5]
let array3 = array1.reduce([]) { array2.contains($1) ? $0 : $0 + [$1] }
print(array3) // "[2, 3, 4, 6]\n"
I'm working on this problem from FreeCodeCamp in JS.
Basically I need to find the difference between two arrays and then return an array with those values i.e. strings and integers.
function diffArray(arr1, arr2) {
//console.log(arr1.length);
var newArr = [];
var dummy = [];
for (var x=0;x<arr1.length;x++) {
if (arr2.indexOf(arr1[x]) === -1) {
newArr = newArr.concat(arr1.slice(x));}}
for (var y=0;y<arr2.length;y++) {
if (arr1.indexOf(arr2[y]) === -1 && newArr.indexOf(arr2[y]) === -1) {
newArr = newArr.concat(arr2.slice(y));
}
}
console.log(newArr);
return newArr;
}
diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);
It almost works. Except these do not work:
[1, 2, 3, 5], [1, 2, 3, 4, 5] - Gives [4, 5].
["diorite", "andesite", "grass", "dirt", "pink wool", "dead shrub"], ["diorite",
"andesite", "grass", "dirt", "dead shrub"] - Gives ["pink wool",
"dead shrub"].
These work though:
[1, "calf", 3, "piglet"], [1, "calf", 3, 4]
[], ["snuffleupagus", "cookie monster", "elmo"]
why are you using slice and concat to feed your output array ?
iterate through arr1
if arr1 has an element which is not in arr2 push it to newArr
iterate though arr2
if arr2 has an element which is not in arr1 push it to newArr
return newArr
I have multiple arrays of different sizes, for instance:
let array1 = [[1, 2, 3], [1, 2, 3]]
let array2 = [[1, 2], [1, 2]]
let array3 = [[1, 2], [1, 2], [1, 2]]
And I wanna join them together so I get the final array:
let finalArray = [[1, 2, 3, 1, 2, 1, 2], [1, 2, 3, 1, 2, 1, 2], [1, 2]]
Any ideia on how can I achieve this goal in a efficient way?
Try like this:
var finalArray:[[Int]] = []
for index in 0..<max(array1.count,array2.count,array3.count) {
finalArray.append([])
if index < array1.count {
finalArray[index].appendContentsOf(array1[index])
}
if index < array2.count {
finalArray[index].appendContentsOf(array2[index])
}
if index < array3.count{
finalArray[index].appendContentsOf(array3[index])
}
}
finalArray // [[1, 2, 3, 1, 2, 1, 2], [1, 2, 3, 1, 2, 1, 2], [1, 2]]
How about:
var arrays = [array1, array2, array3];
var maxSize = Math.max.apply(null, arrays.map(function(a){ return a.length }))
var result = [];
for (var i = 0; i < arrays.length; i++) {
result[i] = [];
for (var j = 0; j < maxSize; j++) {
if (arrays[j][i]) {
result[i] = result[i].concat(arrays[j][i]);
}
}
}
This assumes that what you want to do is end up with a result array that has the same number of elements as the largest input array, putting together the elements in the same position in the input arrays into the output array in the same order as the original arrays.
zip is the obvious function needed to combine the arrays but it is not able to handle the uneven lengths and the map calls may not be as efficient as a C-like algorithm in this case. However as an exercise, here is a more functional approach IF the arrays can be preprocessed to include empty arrays for missing data
let z12 = zip(array1, array2)
let z123 = zip(z12, array3)
let answer = z123.map { [$0.0.0, $0.0.1, $0.1].flatMap { $0 } }
I have changed the arrays from let to var so that they can be appended and I have changed the data for indices 1 to make the answer more obviously correct.
How to remove elements from array that match elements in another array?
Assume we have an array and we loop through it and find out which elements to remove:
var sourceItems = [ ... ]
var removedItems = [SKShapeNode]()
for item : SKShapeNode in sourceItems {
if item.position.y > self.size.height {
removedItems.append(item)
item.removeFromParent()
}
}
sourceItems -= removedItems // well that won't work.
You can use the filter function.
let a = [1, 2, 3]
let b = [2, 3, 4]
let result = a.filter { element in
return !b.contains(element)
}
result will be [1]
Or more succinctly...
let result = a.filter { !b.contains($0) }
Check out the Swift Standard Library Reference
Or you can use the Set type.
let c = Set<Int>([1, 2, 3])
let d = Set<Int>([2, 3, 4])
c.subtract(d)
Be mindful if using the Set option, that your results only be unique values and will not maintain the initial ordering, if that matters to you, whereas the Array filter option will maintain the initial array's order, at least what elements remain.
Swift 3
let c = Set<Int>([65, 1, 2, 3, 1, 3, 4, 3, 2, 55, 43])
let d = Set<Int>([2, 3, 4])
c.subtracting(d)
c = {65, 2, 55, 4, 43, 3, 1}
d = {2, 3, 4}
result = {65, 55, 43, 1}