iOS Get all NSArray into one - ios

I've NSArray with NSArray in. I would like to get all NSArray into one.
I think there is a simple function to use, isn't it ?
Here is what I receive :
(
(
n0eGi1KJWq,
KHGeW32548,
),
(
n0eGi1KJWq
)
)
I would like to get :
(
n0eGi1KJWq,
KHGeW32548,
n0eGi1KJWq
)

A simply loop can be used to create a new array:
NSArray *mainArray = ... // the array containing the other arrays
NSMutableArray *finalArray = [NSMutableArray array];
for (NSArray *innerArray in mainArray) {
[finalArray addObjectsFromArray:innerArray];
}
At this point finalArray will have all of the objects from all of the other arrays.

You can also use #unionOfArrays for this purpose:
NSArray *flatArray = [array valueForKeyPath: #"#unionOfArrays.self"];
If you need a deeper flattening (for three dimensional array), use it twice:
NSArray *flatArray = [array valueForKeyPath: #"#unionOfArrays.self.#unionOfArrays.self"];

Related

Convert Array of Dictionary in single Array

This code:
server_response = [{id:1},{id:2},{id:3},{id:4}]
I am getting above response from server now I want only the list of ids in one array like
ids = [1,2,3,4];
I know we can do by for loop but it takes long time if thousand of ids inside the response array.
Is there any better way to achieve above equation?
NSArray *result = [yourArray valueForKey:#"id"]
From the documentation for NSArray instance method valueForKey:
Returns an array containing the results of invoking valueForKey: using key on each of the array's objects
NSMutableArray *resultArray = [NSMutableArray array];
for (NSDictionary *dict in server_response) {
[resultArray addObject:[dict objectForKey:#"id"]];
}
Try above code. Hope it will help you. Result array has final values
NSArray *server_response = #[#{#"id":#"1"},#{#"id":#"2"},#{#"id":#"3"},#{#"id":#"4"}];
NSMutableArray *resultArray = [NSMutableArray array];
NSString *birdtemp;
for (NSDictionary *object in server_response) {
birdtemp = object[#"id"];
[resultArray addObject:birdtemp];
}
NSLog(#"%#",resultArray);
OutPut: [
1,
2,
3,
4
]

Create array by comparing JSON data to an array

I'm getting access to 'hotel' from json file:
NSArray *hotel = [jsonObject valueForKeyPath:#"location.hotel"];
With print out like (UPDATED):
<__NSCFArray 0x7b254d70>(
{
test = A;
hotel = (
{
luxuryHotels = hotel1;
},
{
luxuryHotels = hotel2;
},
I want to check if the array 'hotel' contains objects from another array 'myHotels' and if it does, create an array with only those objects.
NSArray *myHotels = [NSArray arrayWithArray:hotel.luxuryHotels];
NSMutableArray *hotel2 = [[NSMutableArray alloc] init];
for (NSArray *object in hotel) {
NSMutableSet *set1 = [NSMutableSet setWithArray: object];
NSSet *set2 = [NSSet setWithArray: myHotels];
[set1 intersectSet: set2];
NSArray *resultArray = [set1 allObjects];
NSLog(#"resultArray is %#",resultArray);
[hotel2 addObject:resultArray];
}
The print for 'hotel2' is something like: (
),( hyatt
),(
)
Is there a way to get a string of only hyatt? Or a way to combine the dictionaries of the array so it show as on list if there are more than one hotel listed?
It's still not 100% clear what the data structure looks like but you could try something like this
Collapse your initial data structure (array of arrays) into just an array, then convert this into a mutable set
NSArray *flattenedHotels = [jsonObject valueForKeyPath:#"#distinctUnionOfArrays.location.hotel"];
NSMutableSet *hotels = [NSMutableSet setWithArray:flattenedHotels];
Next you just perform an intersection with myHotels
[hotels intersectSet:[NSSet setWithArray:myHotels]];
NSArray *result = hotels.allObjects;

Projection of properties of objects in NSArray/NSSet collections

I have an array of objects that I convert to a NSSet:
NSArray *arr = #[#{ #"someProp": #21, #"unnecessaryProp": #"tada" }, ... ];
NSSet *collection = [NSSet setWithArray:arr];
I would like to project the properties I want (by key) out of each object in the set and end up with a new array like:
NSArray *projectedArray = [collection allObjects]; // #[#{ "someProp": #21 }, ... ], "unnecessaryProp" has been removed
Besides enumeration, is there any other way, perhaps NSPredicate?
NOTE: The objects in the array are subclasses of NSObject, in my example I mentioned a NSDictionary
Since NSPredicate does not do projections, you would end up enumerating the set. I would enumerate it with a block, and project the keys in the individual dictionaries like this:
NSArray *keep= #["someProp"];
NSMutableArray *res = [NSMutableArray array];
[collection enumerateObjectsUsingBlock:^(id dict, BOOL *stop) {
NSArray *values = [dict objectsForKeys:keep notFoundMarker:#""];
[res addObject:[NSDictionary dictionaryWithObjects:values forKeys:keep]];
}];
EDIT : (in response to comments)
I should have mentioned that the objects inside the array are subclasses of NSObject and objectsForKeys is not a method.
Then you could use MartinR's suggestion to build a dictionary using KVC:
NSArray *keep= #["someProp"];
NSMutableArray *res = [NSMutableArray array];
[collection enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
[res addObject:[obj dictionaryWithValuesForKeys:keep]];
}];
If you only need the values for one property of the objects in a collection of type NSSet or NSArray or their subclasses, you can use the KVC method valueForKey:
NSArray *dogs = #[#{#"name" : #"Fido",
#"toys" : #[#"Ball", #"Kong"]},
#{#"name" : #"Rover",
#"toys" : #[#"Ball", #"Rope"]},
#{#"name" : #"Spot",
#"toys" : #[#"Rope", #"Kong"]}];
NSArray *vals = [set valueForKey:#"name"];
NSLog(#"%#", vals);
The above code prints the following on the console:
2014-05-16 09:26:58.293 xctest[17223:303] (
Fido,
Rover,
Spot
)
If you need the values of several properties of the objects in the collection, use dictionaryWithValuesForKeys:. Given the same array as in the previous example, the following code...
NSDictionary *dict = [dogs dictionaryWithValuesForKeys:#[#"name", #"toys"]];
NSLog(#"%#", dict);
produces an array of dictionaries, and logs the following output:
2014-05-16 09:35:34.793 xctest[17275:303] {
name = (
Fido,
Rover,
Spot
);
toys = (
(
Ball,
Kong
),
(
Ball,
Rope
),
(
Rope,
Kong
)
);
}
This works regardless of whether the objects in the target collections are instances of NSDictionary or of custom classes.
you can use indexOfObjectPassingTest on your array or NSSet.
__block NSUInteger maxIdex = [_myArrray count]-1;
__block NSMutableIndexSet* objToRemove = [[NSMutableIndexSet alloc]init];
[_myArrray indexOfObjectPassingTest:^(id object, NSUInteger idx, BOOL * stop){
MyObject *obj = (MyObject*)object;
if(....){
[objToRemove addIndex:[_myArrray indexOfObject:obj]];
}
*stop = (idx == maxIdex);
return *stop;
}];
[_myArrray removeObjectsAtIndexes:objToRemove];

Sort an NSArray by another nsarray with ids

i have 2 nsarrays
1 with nsdictionary's another with nsnumbers
NSArray *arr1 = #[#{#"id":#1},#{#"id":#2},#{#"id":#3},#{#"id":#4}];
NSArray *arr2 = #[#3,#1,#4,#2];
and i want to sort my arr1 through their id following the order of arr2
is this possible?
The problem with using sortedArrayUsingComparator: is you start dealing with O(n^2) lookup times. For each sort comparison in the first array, you have to do a lookup in the second array.
Your best bet is to take advantage of a hash table to reduce that to O(n) average complexity.
Your first step is to create a dictionary using id as a key. The result would look something like #{#1: #{#"id":#"1"}, ...}. Then you just have to construct an array by looping through arr3 and grabbing the values.
NSArray *arr1 = #[#{#"id":#1},#{#"id":#2},#{#"id":#3},#{#"id":#4}];
NSArray *arr2 = #[#3,#1,#4,#2];
NSMutableDictionary *map = [NSMutableDictionary dictionary];
for (NSDictionary *item in arr1) {
map[item[#"id"]] = item;
}
NSMutableArray *arr3 = [NSMutableArray array];
for (id key in arr2) {
[arr3 addObject:map[key]];
}
This solution of course assumes parity between the two arrays. If arr2 has an element not in arr1 it will crash when trying to add nil to arr3. If arr1 has a value not in arr2 it will be excluded from arr3. These are risks you will have to address based on your requirements.
Here is how you can do it by using a custom comparator:
NSArray* sorted= [arr1 sortedArrayUsingComparator: ^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2) {
return [arr2 indexOfObject:obj1[#"id"]] - [arr2 indexOfObject:[obj2[#"id"]];
}];
I exploited the fact that NSComparisonResult has +1 to represent an ascending order, -1 for descending and 0 to represent the same order.
- (NSArray*) sortedArray
{
NSArray *arr1 = #[#{#"id":#1},#{#"id":#2},#{#"id":#3},#{#"id":#4}];
NSArray *arr2 = #[#3,#1,#4,#2];
NSMutableArray *mutableArray = [NSMutableArray new];
for (NSNumber *number in arr2)
{
for (NSDictionary* dictionary in arr1)
{
NSNumber *number2 = dictionary[#"id"];
if ([number isEqual:number2])
{
[mutableArray addObject:dictionary];
break;
}
}
}
return mutableArray;
}

NSMutableDictionary -- using allKeysforObject not retrieving array values

NSMutableDictionary *expense_ArrContents = [[NSMutableDictionary alloc]init];
for (int i = 1; i<=4; i++) {
NSMutableArray *current_row = [NSMutableArray arrayWithObjects:#"payer_id",#"Expense_Type_id",#"Category_Id",#"SubCategory_Id",nil];
[expense_ArrContents setObject:current_row forKey: [NSNumber numberWithInt:i]];
}
NSArray *newArray = [expense_ArrContents allKeysForObject:#"payer_id"];
NSLog(#"%#",[newArray description]);
i want to get the list of key values containing the particular object which is in the array of values stored in nsmutabledictionary for a particular key.
In the line where you get all the keys ([expense_ArrContents allKeysForObject:#"payer_id"];) you actually get keys for an object that is not in any of the array's items. This #"player_id" is different object than the #"player_id" you added in current_row. In fact, maybe all of your rows have different #"player_id" objects (except if the compiler has made some optimization - maybe it threats that same string literal as one object instead of creating new object for each iteration).
Try creating an NSString object for the #"player_id" which you add to the current_row and then get all the keys for that same object:
NSString* playerId = #"player_id";
for(){
NSMutableArray *current_row = [NSMutableArray arrayWithObjects: playerId,...];
...
}
NSArray *newArray = [expense_ArrContents allKeysForObject:playerId];
Your NSArray *newArray = [expense_ArrContents allKeysForObject:#"payer_id"]; will not return any value because in expense_ArrContents there is no such key(#"payer_id"), instead there are keys like 1,2,3 etc.What is your requirement?Want to see what all keys are there in expense_ArrContents just log
NSArray*keys=[expense_ArrContents allKeys];
Try this :
NSMutableArray *array_key=[[NSMutableArray alloc]init];
for (NSString *key in expense_ArrContents) {
if ([[expense_ArrContents objectForKey:key] containsObject:#"payer_id"]) {
[array_key addObject:key];
}
}

Resources