Swift compare arrays, anyone has an idea how to solve it? - arrays

Could someone tell me how I can solve this problem? I have two arrays in array 1 change values, array 2 has to synchronize with the first one, but without losing the value positions. I have tried with difference(from:) but it reorders the values of array 2. Here as it should be, thank you very much for your help.
let array1 = ["01", "06", "17", "22", "33", "45", "04"]
var array2 = ["04", "17", "22", "10", "01", "34"]
//
...
// Result
var array2 = ["04", "17", "22", "01", "06", "33", "45"]
The order of the values in array 2 must remain the same, delete those missing from array 1 and add those missing from array 1 to the end of array 2.

Naive solution:
Copy array1 to a temporary var temp
Loop through the indexes of temp in reverse order. If a value from temp exists in array2, remove it.
Append temp to array2.
That would have poor (roughly O(n^2), or rather O(array1.count*array2.count)) time performance for large arrays, since the array contains() function is O(n). You could speed it up by using a set to track items in array2.

This is the best solution I can get 😉
let array1 = ["01", "06", "17", "22", "33", "45", "04"]
var array2 = ["04", "17", "22", "10", "01", "34"]
let remove = (array2.filter{!array1.contains($0)})
let append = (array1.filter{!array2.contains($0)})
for i in remove {
array2 = array2.filter {$0 != i}
}
array2.append(contentsOf: append)
print("array2:\(array2)")
// array2:["04", "17", "22", "01", "06", "33", "45"]

Related

How to convert the position of an array into a single array?

What happens is that I have the following position of an array rows[0] = ["1", "2", "3", "4"] which stores certain data: what I want to do is to create a new array with the data that has the position 0 of the array rows so that, for example, I have a new vector = ["1", "2", "3", "4"], so that I could do, for example, console. log(new[0]); and have as output "1", and likewise with the other data of the new vector. I was thinking about doing it with some for or while loop, but I can't find the way to do it since row is of position 0.
you should try with destructuring
var rows = [];
rows[0] = ["1", "2", "3", "4"];
const [new] = rows
console.log(new[0]);

Swift : what is the right way to split up a [String] resulting in a [[String]] with a given example?

Starting with a large [String] and a given subarray size, what is the best way I could go about splitting up this array into smaller arrays? (The last array will be smaller than the given subarray size).
Concrete example:
Split up ["1","2","3","4","5","6","7","8","9"] with max split size 4
The code would produce [["1","2","3","4"],["4","5","6","7"],["7","8","9"]]
Obviously I could do this a little more manually, but I feel like in swift something like map() or reduce() may do what I want really beautifully.
You can map over the indices into you array:
extension Array {
func chunked(size: Int) -> [[Element]] {
let cnt = self.count
return stride(from: 0, to: cnt, by: size).map {
let end = Swift.min($0 + size, cnt)
return Array(self[$0..<end])
}
}
}
["1","2","3","4","5","6","7","8","9"].chunked(size: 4)
// -> [["1", "2", "3", "4"], ["5", "6", "7", "8"], ["9"]]
["1","2","3","4","5","6","7","8","9"].chunked(size: 3)
// -> [["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"]]

I want to push more arrays into this Hash?

i want to push an array into this part, i'm a newbie in Ruby
#edge_weights = {[position, position2] => node_distance}
That is a Hash? i think i want to push some other hashes of the same way to have a result like this:
{["1", "2"]=>2445, ["2", "3"]=>2015, ["2", "4"]=>1547, ["3", "4"]=>939, ["5", "1"]=>1548}
Not like this:
{["1", "2"]=>111},{["2", "3"]=>222},{["1", "3"]=>333}
How can i achieve this?. Sorry for my bad english :(
Presumably you will begin with some data such as the following array of arrays:
arr = [["1", "2", 2445], ["2", "3", 2015], ["2", "4", 1547],
["3", "4", 939], ["5", "1", "7", 1548], ["1", "2", -71]]
Step one is to create an empty hash:
h = {}
Now iterate over the elements of arr to build the hash h.
arr.each do |a|
*first, last = a
h[first] = last
end
#=> [["1", "2", 2445], ["2", "3", 2015], ["2", "4", 1547],
# ["3", "4", 939], ["5", "1", "7", 1548], ["1", "2", -71]]
We want the value of h, not the above return value.
h #=> {["1", "2"]=>-71, ["2", "3"]=>2015, ["2", "4"]=>1547,
# ["3", "4"]=>939, ["5", "1"]=>1548, ["5", "1", "7"]=>1548}
Note that Ruby's splat operator1 is used to break up an array in various ways:
*first, last = ["5", "1", "7", 1548]
first
#=> ["5", "1", "7"]
last
#=> 1548
Is the result above for h what you were expecting? Recall that hashes have unique keys. After the first element of arr is passed to the block we execute
h[["1", "2"]] = 2445
so that h becomes { ["1", "2"]=>2445 }. Later, when the last element of arr--which has the same key (["1", "2"])--is passed to the block, we execute
h[["1", "2"]] = -71
which overwrites the value of that key. If you'd prefer to keep the value of the first key encountered you could write
arr.each do |a|
*first, last = a
h[first] = last unless h.key?(first)
end
See Hash#key? (aka, has_key? and include?). (Aside: you could write ...if !h.key?(first), ! read not, but it's generally clearer to avoid negation by using unless.)
The "Ruby way" of writing the original construct is to use the method Enumerable#each_with_object and to splat the block variables a:
arr.each_with_object({}) do |(*first, last),h|
h[first] = last
end
#=> {["1", "2"]=>-71, ["2", "3"]=>2015, ["2", "4"]=>1547,
# ["3", "4"]=>939, ["5", "1"]=>1548, ["5", "1", "7"]=>1548}
This avoids the need to use a separate statement to create an empty hash and the code block returns the value of h.
(Don't worry if you don't understand this.)
One other common way to construct a hash is to use the method Hash#update (aka merge!):
arr.each_with_object({}) do |(*first, last),h|
h.update({ first=>last })
end
Note Ruby allows a shorthand version of the second line:
h.update(first=>last)
1 See "Multiple variable assignment" here.
you can pass array as key and assign value to it:
> edge_weights = {}
> edge_weights[["1","2"]] = 2445
> edge_weights[["2", "4"]] = 1547
> edge_weights
#=> {["1", "2"]=>2445, ["2", "4"]=>1547}

Swift - pruning elements from an Array, converting integer strings to integers

I have an array that contains numbers and empty strings, like ["", "2", "4", "", "", "1", "2", ""]. I would like to pare this down to a list of numbers, like [2,4,1,2].
My first effort split this into two steps, first strip out the empty strings, then do the string-to-integer conversion. However, my code for step one isn't working as desired.
for (index,value) in tempArray.enumerate(){
if value == "" {
tempArray.removeAtIndex(index)
}
}
This fails, I believe because it is using the index values from the original, complete array, though after the first deletion they are not longer accurate.
What would be a better way to accomplish my goal, and what is the best way to convert the resulting array of integer strings to an array of integers?
var str = ["", "2", "4", "", "", "1", "2", ""]
let filtered = str.filter {$0 != "" }
let intArr = filtered.map {($0 as NSString).integerValue}
With Swift 2 we can take advantage of flatMap and Int():
let stringsArray = ["", "2", "4", "", "", "1", "2", ""]
let intsArray = stringsArray.flatMap { Int($0) }
print(intsArray) // [2, 4, 1, 2]
Explanation: Int() returns nil if the string does not contain an integer, and flatMap ignores nils and unwraps the optional Ints returned by Int().

array arithmetic

I have one array as this:
"4": "40000",
"5": "3000",
"6": "200",
"7": "10",
"8": "1"
I want to have an another array which adds all the bigger ones to smaller ones. I hope it makes sense. How can I achieve this?
"4": "43211",
"5": "3211",
"6": "211",
"7": "11",
"8": "1"
Just to find an efficient method so language doesn't matter but if necessary I use php or javascript. It is an associative array so it is not sorted. And another trick is that array might or might not contain some elements. So for example "6" or "8" might be missing.
for i = 7 to 4 decreasing
array [i] += array [i+1]

Resources