Obtain values that match in two different arrays in Swift - arrays

In a service request, I obtain an array with this structure:
(
{
key = 1;
val = "Cookies";
},
{
key = 2;
val = Restaurante;
},
{
key = 22;
val = "Cereals";
},
{
key = 16;
val = "Shirts";
}
In a second request, I obtain another array of values that are related to the array of the first request:
▿ Optional<NSArray>
▿ some : 5 elements
- 0 : 1
- 1 : 2
- 2 : 5
- 3 : 19
- 4 : 20
What I need is to show in a tableView the text of the first array whose keys I obtain in the second array, how could I do that?

It looks like you obtain that types of arrays
struct ArrayObject {
let key: Int
let value: String
}
let objectArray: [ArrayObject] = []
let keysArray: [Int] = []
Then you need to use filter to determine what keys are contains in second array:
// if you need objects
let filteredObjectsResult = objectArray.filter { keysArray.contains($0.key) }
// if you need values only
let filteredValuesResult = filteredObjectsResult.map { $0.value }

Related

slice to create 2 dimensional array

I want to create a 2 dimensional array
array items has 32 objects
every array contains 9 objects each with the remainder (32 % 9 = 5) in the last array
with the code below, I am expecting :
I am expecting : [Array(9), Array(9), Array(9), Array(5)]
const returnProductsArrays = (items) => {
let TwoDimensionalArray = []
let remainder = items.length % 9
let i = 0
while (i < (items.length - remainder)) {
let array = items.slice(i, 9)
TwoDimensionalArray.push(array)
i += 9
}
const array = items.slice(i + 1, remainder)
TwoDimensionalArray.push(array)
return TwoDimensionalArray
}
only the 1st array has objects, the rest is empty.
What am I am missing ?
slice does not mutate vs. splice . why is the array empty on the 2 iteration in the while loop
there are two mistakes, I will point below:
const returnProductsArrays = (items) => {
let TwoDimensionalArray = []
let remainder = items.length % 9
let i = 0
while (i < (items.length - remainder)) {
// second param needs to be "i + 9"
let array = items.slice(i, i + 9)
TwoDimensionalArray.push(array)
i += 9
}
// here you need just the "i" param (not i+1), and it will slice till the end of array
const array = items.slice(i)
TwoDimensionalArray.push(array)
return TwoDimensionalArray
}

how to combine duplicate key in dictionary and sum up values in swift?

var dictionary: [String : Any] = [:]
for revenueItem in revenues {
if let currentValue = dictionary[revenueItem.customerName] {
dictionary[revenueItem.customerName] = [currentValue] + [revenueItem.revenue]
print("hellooooooooooo \(currentValue)")
} else {
dictionary[revenueItem.customerName] = [revenueItem.revenue]
}
}
like i have a 2 customer name with the same keys but different values. i want to sum up their values and make only one key in output but have a total value.
In my tableview cell appears duplicated and not sum up the values and the customername (key) is also duplicated. please help.. i tried everything but failed to correct the output.
You can use Dictionary.init<S>(_ keysAndValues: S, uniquingKeysWith combine: (Value, Value) throws -> Value), which takes a Sequence of tuples, storing the key-value pairs and a closure, which defines how to handle duplicate keys.
// Create the key-value pairs
let keysAndValues = revenues.map { ($0.customerName, $0.revenue) }
// Create the dictionary, by adding the values for matching keys
let revenueDict = Dictionary(keysAndValues, uniquingKeysWith: { $0 + $1 })
Test code:
struct RevenueItem {
let customerName: String
let revenue: Int
}
let revenues = [
RevenueItem(customerName: "a", revenue: 1),
RevenueItem(customerName: "a", revenue: 9),
RevenueItem(customerName: "b", revenue: 1)
]
let keysAndValues = revenues.map { ($0.customerName, $0.revenue) }
let revenueDict = Dictionary(keysAndValues, uniquingKeysWith: { $0 + $1 })
revenueDict // ["a": 10, "b": 1]

Counting unique ids within nested array using Swift

I have the following nested array and I'm trying to count how many items with unique ids there are. In the array below the count should be 2.
Array is of type List<SolData> it comes from Realm
class SolData: Object {
#objc dynamic var uid = "";
#objc dynamic var id = "";
}
extension SolData: ListDiffable {
func diffIdentifier() -> NSObjectProtocol {
return uid as NSObjectProtocol
}
func isEqual(toDiffableObject object: ListDiffable?) -> Bool {
if let object = object as? SolData {
return uid == object.uid
}
return false
}
}
Print of the array.
(
[0] SolData {
uid = sdasd;
id = jmX3;
},
[1] SolData {
uid = gfd;
id = jmX3;
},
[2] SolData {
uid = hgfd;
id = jmX3;
},
[3] SolData {
uid = terw;
id = jmX3;
},
[4] SolData {
uid = fgg;
id = GFdda;
}
)
I tried to use map in the following way
var count = 0;
var prevId = "";
let uniqueSols = diff.sol.map{ (s) -> Int in
if s.id != prevId {
count = count + 1;
prevId = s.id;
}
return count;
}
print(uniqueSols);
But I get the following error.
SWIFT RUNTIME BUG: unable to demangle type of field '_transform'. mangled type name is 'q_7ElementSTQzc'
2018-10-27 14:26:08.793528+0300 App[23634:611928] SWIFT RUNTIME BUG: unable to demangle type of field '_transform'. mangled type name is 'q_7ElementSTQzc', _transform: ())
To reproduce your code, I am going to mock the SolData class and add an initializer to make instantiation easier:
class SolData {
var uid: String = ""
var id: String = ""
init(uid: String, id: String) {
self.uid = uid
self.id = id
}
}
Let's create a few of instances:
let zero = SolData(uid: "sdasd", id: "jmX3")
let one = SolData(uid: "gfd", id: "jmX3")
let two = SolData(uid: "hgfd", id: "jmX3")
let three = SolData(uid: "terw", id: "jmX3")
let four = SolData(uid: "fgg", id: "GFdda")
And group them in an array:
let array = [zero, one, two, three, four]
To get only instances that have unique ids, let's use reduce(into:) :
let uniqueIds = array.reduce(into: Set<String>(), { $0.insert($1.id)})
The count property of uniqueIds is the number of unique ids in array:
let uniqueIdsCount = uniqueIds.count //2
If you want an array of instances with unique ids, use the following:
let instancesWithUniqueIds = array.reduce(into: [SolData]()) { accumulator, element in
if accumulator.allSatisfy({ $0.id != element.id}) {
accumulator.append(element)
}
}
accumulator.allSatisfy({ $0.id != element.id}) maybe replaced by accumulator.contains(element) and making SolData conform to Hashable.

Find element in an array of object

I created an array of objects:
var fullMonthlyList = [SimulationMonthly]()
The class here:
class SimulationMonthly {
var monthlyMonthDuration: NSNumber = 0
var monthlyYearDuration: NSNumber = 0
var monthlyFullAmount: NSNumber = 0
var monthlyAmount: Int = 0
init(monthlyMonthDuration: NSNumber, monthlyYearDuration: NSNumber, monthlyFullAmount: NSNumber, monthlyAmount: Int){
self.monthlyMonthDuration = monthlyMonthDuration
self.monthlyYearDuration = monthlyYearDuration
self.monthlyFullAmount = monthlyFullAmount
self.monthlyAmount = monthlyAmount
}
}
I just did append to populate it, now I want to find for example if they're an existing value, for example monthlyAmount equals to "194" by search in the array, how can I do ? I have tried filter and contains but I get errors.
What I've tried:
if self.fullMonthlyList.filter({ $0.monthlyAmount == self.monthlyAmount.intValue }) { ... }
Error:
Cannot invoke 'filter' with an argument list of type '((SimulationMonthly) throws -> Bool)'
You can do:
if let sim = fullMonthlyList.first(where: { $0.monthlyAmount == 194 }) {
// Do something with sim or print that the object exists...
}
This will give you the first element in your array where monthlyAmount equals 194.
If you want all elements with that condition, you can use filter:
let result = fullMonthlyList.filter { $0.monthlyAmount == 194 }
If you don't need the object at all but you just want to know if one exists, then contains would be enough:
let result = fullMonthlyList.contains(where: { $0.monthlyAmount == 194 })
Here's a simple playground example of filtering objects based on matching a property. You should be able to expand it to your situation.
class Item {
var value: Int
init(_ val: Int) {
value = val
}
}
var items = [Item]()
for setting in 0..<5 {
items.append(Item(setting))
}
func select(_ with: Int) -> [Item] {
return items.filter { $0.value == with }
}
let found = select(3)

Flex 3 Actionscript Array Subtract function

Can anyone tell me how to compare two arrays and delete the common terms in ActionScript?
Eg:
Array1 = [2,4,6,8,10,12]
Array2 = [1,2,3,4,5,6,7,8,9,10,11]
Array1 - Array2 = [12]
If you use ActionLinq, it is very easy to do set mathematics like this:
var array1:Array = [2,4,6,8,10,12];
var array2:Array = [1,2,3,4,5,6,7,8,9,10,11];
var subtraction:Array = Enumerable.from(array1)
.except(Enumerable.from(array2))
.toArray();
You can filter using a custom function.
This is not an optimized way of filtering a difference of arrays, but it'll get the job done.
subtraction = Array1.filter(function(item:*, index:int, arr:Array){
var i:int;
var l:int;
l = Array2.length;
for ( i=0; i < l; i++ )
{
if ( Array2[i] == item )
{
return false;
}
}
return true;
});
If you wish to knock out all duplicates from an Array then I suggest that you use a Set to make the lookup speed as fast as possible:
const a : Array = [ 2, 3, 4 ];
const b : Array = [ 3, 4, 5 ];
// Create a Set for Array 'b' to provide a fast lookup table.
const setB : Object = {};
var prop : *;
for each (prop in b) {
setB[key] = true
};
// Find all values which only belong in Array 'a'.
const uniqueToA : Array = [];
for each (prop in a) {
if (setB[prop] === undefined) {
uniqueToA.push(prop);
}
}
If you find yourself doing a lot of work with collections then I would advise you invest in a Collections Framework such as AS3Commons Collections.

Resources