I have 2 arrays:
Array one: (#"26", #"26", #"25", #"25", #"3", #"3", #"4", #"4")
Array two: (#"sticker", #"sticker", #"sticker", #"sticker", #"sticker", #"frame", #"frame", #"frame")
Edit
These 2 arrays are connected like this:
26 - sticker
26 - sticker
25 - sticker
25 - sticker
3 - frame
3 - frame
4 - frame
4 - frame
I'm getting unique value in array one and putting it in another array like this:
NSArray *uniqueArrayOne = [[NSSet setWithArray:arrayOne] allObjects];
So uniqueArrayOne looks like this:
(26, 25, 3, 4)
I want uniqueArrayTwo to also be arrange like how uniqueArrayOne was arranged. I want uniqueArrayTwo to look like this:
(sticker, sticker, frame, frame)
What do I do?
Edit
Here is another example:
Array one: (#"TONY", #"SANSA", #"BILL", #"BILL", #"STEVE", #"STEVE")
Array two: (#"STARK", #"STARK", #"GATES", #"GATES", #"JOBS", #"JOBS")
The results should be like this:
uniqueArrayOne :(TONY, SANSA, BILL, STEVE)
uniqueArrayTwo :(STARK, STARK, GATES, JOBS)
uniqueArrayTwo is arrange depending on uniqueArrayOne.
I would solve it this way
- (void)uniqueArrayFinder
{
NSArray *array1 = [[NSArray alloc] initWithObjects:
#"TONY", #"SANSA", #"BILL", #"BILL", #"STEVE", #"STEVE",nil];
NSArray *array2 = [[NSArray alloc] initWithObjects:
#"STARK", #"STARK", #"GATES", #"GATES", #"JOBS", #"JOBS",nil];
NSMutableArray *combinedArray = [[NSMutableArray alloc] init];
for (int i=0; i<[array1 count];i++)
{
NSString *arrayVal1 = [array1 objectAtIndex:i];
NSString *arrayVal2 = [array2 objectAtIndex:i];
NSString *combinedStr = [NSString stringWithFormat:#"%# %#", arrayVal1, arrayVal2];
[combinedArray addObject:combinedStr];
}
//this gives uniqe values
NSSet *uniqueEvents = [NSSet setWithArray:combinedArray];
[combinedArray removeAllObjects];
[combinedArray addObjectsFromArray:[uniqueEvents allObjects]];
NSLog(#"combinedArray: %# ...", combinedArray);
}
Output:
combinedArray: (
"STEVE JOBS",
"TONY STARK",
"SANSA STARK",
"BILL GATES"
) ...
You can achieve the desired result with the following,
NSArray *arr1 = #[#"26", #"26", #"25", #"25", #"3", #"3", #"4", #"4"];
NSArray *arr2 = #[#"sticker", #"sticker", #"sticker", #"sticker", #"sticker", #"frame", #"frame", #"frame"];
NSDictionary *dict = [NSDictionary dictionaryWithObjects:arr2
forKeys:arr1];
NSArray *distinctArr1 = [[NSOrderedSet orderedSetWithArray:arr1] array];
NSMutableArray *distinctArr2 = [NSMutableArray array];
for (NSString *num1 in distinctArr1) {
[distinctArr2 addObject:dict[num1]];
}
// Your distinctArr2 is sorted based on distinctArr1's indices
Try this one.
NSArray *arrayOne = #[#"TONY", #"SANSA", #"BILL", #"BILL", #"STEVE", #"STEVE"];
NSArray *arrayTwo = #[#"STARK", #"STARK", #"GATES", #"GATES", #"JOBS", #"JOBS"];
NSArray *uniqueArrayOne = [[NSSet setWithArray:arrayOne] allObjects];
NSMutableArray *uniqueArrayTwo = [NSMutableArray array];
[uniqueArrayOne enumerateObjectsUsingBlock:^(id _Nonnull obj1, NSUInteger idx, BOOL * _Nonnull stop) {
NSUInteger found = [arrayOne indexOfObjectPassingTest:^BOOL(id _Nonnull obj2, NSUInteger idx, BOOL * _Nonnull stop) {
return [(NSString *)obj2 isEqualToString:(NSString *)obj1];
}];
[uniqueArrayTwo addObject:[arrayTwo objectAtIndex:found]];
}];
NSLog(#"%#, %#", uniqueArrayOne, uniqueArrayTwo);
Related
If you have an array of dictionaries, how do I create a new array containing all the keys present for each dictionary in the array ?
NSArray *array = #[#{#"key1" : #"value 1"},
#{#"key2" : #"value 2"},
#{#"key3" : #"value 3"} ];
// how to achieve this?
NSArray *allKeys = #{#"key1", #"key2", #"key3"};
If you know that each element in the array is an NSDictionary, you can call the allKeys method on each item in the array. I've added a type check to this example in case your array contains other objects that are not NSDictionary:
NSArray *array = #[#{#"key1" : #"value 1"},
#{#"key2" : #"value 2"},
#{#"key3" : #"value 3"}];
NSMutableArray *allKeys = [#[] mutableCopy];
for (id obj in array) {
if ([obj isKindOfClass:[NSDictionary class]]) {
NSDictionary *dict = obj;
[allKeys addObjectsFromArray:[dict allKeys]];
}
}
NSLog(#"%#", allKeys);
Logs:
2016-04-20 11:38:42.096 ObjC-Workspace[10684:728578] (
key1,
key2,
key3
)
And if you need an immutable NSArray instead of an NSMutableArray:
NSArray *allKeysImmutable = [allKeys copy];
plz use this code, I think it helps you
NSArray *array = #[#{#"key1" : #"value 1"},
#{#"key2" : #"value 2"},
#{#"key3" : #"value 3"} ];
NSMutableArray *key_array=[NSMutableArray array];
for (NSDictionary *dictionary in array) {
NSArray *key_dictionary=[dictionary allKeys];
for (NSString *string_key in key_dictionary) {
[key_array addObject:string_key];
}
}
NSLog(#"%#",key_array);
Although Objective-C lacks an array-flattening method, you can nevertheless simplify the outer step:
NSMutableArray *result = [[NSMutableArray alloc] init];
for(NSArray *keys in [array valueForKey:#"allKeys"])
[result addObjectsFromArray:keys];
return [result copy];
Or, if you need keys deduplicated:
NSMutableSet *result = [[NSMutableSet alloc] init];
for(NSArray *keys in [array valueForKey:#"allKeys"])
[result unionSet:[NSSet setWithArray:keys]];
return [result allObjects];
... the only type assumption being (only slightly looser than) that array is all dictionaries. If you can annotate the collections any further then I recommend that you do.
I have an array like this:
NSArray *needSortedArray = #[#"Alex", #"Rachel", #"Mohamad"];
and an array of index like this:
NSArray *indexArray = #[#1, #0, #2];
So the output I want will look like this:
needSortedArray = #[#"Rachel", #"Alex", #"Mohamad"];
How can I do this? Is it possible?
Try this:
NSArray *unsortedArray = #[#"Alex", #"Rachel", #"Mohamad"];
NSArray *indexArray = #[#1, #0, #2];
NSMutableArray * sortedArray = [[NSMutableArray alloc] initWithCapacity:unsortedArray.count];
for (NSNumber * num in indexArray)
{
[sortedArray addObject:[unsortedArray objectAtIndex:num.integerValue]];
}
//now sortedArray has sorted objects.
Solution that supports any comparable types of indexes:
NSArray<NSString*> *unsortedArray = #[#"Alex", #"Rachel", #"Mohamad", #"Andrew"];
NSArray<NSNumber*> *indexArray = #[#1, #12, #23, #12];
NSParameterAssert([indexArray count] == [unsortedArray count]);
NSArray* sorted = [unsortedArray sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
NSNumber* index1 = indexArray[[unsortedArray indexOfObjectIdenticalTo:obj1]];
NSNumber* index2 = indexArray[[unsortedArray indexOfObjectIdenticalTo:obj2]];
NSComparisonResult result = [index1 compare:index2];
return result;
}];
NSLog(#"Sorted array: %#", sorted);
I have an array of values, and I'd like to sort it from highest to lowest values. Here's my array:
#[#0.985517248005697843460382, #0.000103821940243745174581, #0.002930049254083499140483, #0.006089428685598983863325, #0.000169959081717878927225 #0.038708805305937427077012, #0.005785644142951103588435, #0.003949420720490224266663 #0.003306789895982742942537, #0.005520713777168946394258];
What's the most efficient way to create a new array, but instead of containing the sorted values, it would contain the indexes from the original array?
Currently this is what I'm doing:
NSArray *array = #[#3, #5, #7, #2, #4, #4.1, #1, #10];
NSArray *sortedArray = [array sortedArrayUsingSelector: #selector(compare:)];
NSMutableArray *arraySortedByOriginalIndexes = [[NSMutableArray alloc] init];
for (int i = 0; i < sortedArray.count; i++) {
NSUInteger index = [array indexOfObject:sortedArray[i]];
[arraySortedByOriginalIndexes addObject:#(index)];
}
Here is the simple solution if no numbers in array are equal.
NSArray *sortedArray = [array sortedArrayUsingSelector: #selector(compare:)];
NSMutableArray *mutableIndexes = [NSMutableArray array];
for (NSNumber *number in sortedArray) {
[mutableIndexes addObject:#([array indexOfObject:number])];
}
NSArray *indexes = [mutableIndexes copy];
Again, it only works when no numbers are equal.
NSArray A = #[[[#"id":#"3"]], [[#"id":#"4"]] ,[[#"id":#"c"]],[[#"id":#"f"]]];
NSArray idArray = #[#"c", #"3", #"4",#"f"];
Just a example I assumed.
How can I sort A by its id with idArray?
That is, I want A to become:
NSArray A= #[[[#"id":#"c"]], [[#"id":#"3"]] ,[[#"id":#"4"]],[[#"id":#"f"]]];
Now, I want to ask for an algorithm to sort array A to get the desired result.
---I get my answer when I search in google:
NSArray *sorter = #[#"B", #"C", #"E"];
NSMutableArray *sortee = [#[
#[#"B", #"abc"],
#[#"E", #"pqr"],
#[#"C", #"xyz"]
] mutableCopy];
[sortee sortUsingComparator:^(id o1, id o2) {
NSString *s1 = [o1 objectAtIndex:0];
NSString *s2 = [o2 objectAtIndex:0];
NSInteger idx1 = [sorter indexOfObject:s1];
NSInteger idx2 = [sorter indexOfObject:s2];
return idx1 - idx2;
}];
If you want to compare both array you can use
NSArray *array1=#[#"3",#"4",#"c","f"];
NSArray *array2=#[#"c",#"3",#"4","f"];
array1=[array1 sortedArrayUsingSelector:#selector(compare:)];
array2=[array2 sortedArrayUsingSelector:#selector(compare:)];
if ([array1 isEqualToArray:array2]) {
NSLog(#"both are same");
}
else{
NSLog(#"both are differnt");
}
or If you want to get common elements from 2 array use
NSMutableSet* set1 = [NSMutableSet setWithArray:array1];
NSMutableSet* set2 = [NSMutableSet setWithArray:array2];
[set1 intersectSet:set2]; //this will give you only the obejcts that are in both sets
NSArray* result = [set1 allObjects];
This would be a better way to make a dictionary for A. And then sorting based on their specific values like IQ, Name etc.
NSArray A = #[[[#"id":#"3"]], [[#"id":#"4"]] ,[[#"id":#"c"]],[[#"id":#"f"]]];
NSArray idArray = #[#"c", #"3", #"4",#"f"];
NSMutableArray *array = [NSMutableArray array];
for (int id = 0;idx<[A count];id++) {
NSDictionary *dict = #{#"Name": A[id],#"IQ":idArray[id]};
[array addObject:dict];
}
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:#"IQ" ascending:NO];
[array sortUsingDescriptors:#[descriptor]]
I'm currently attempting to use CHCSVParser to parse through a CSV file containing over 1500 entries, and 8 rows. I've successfully managed to parse through the file, and what I get is an NSArray of NSArrays of NSStrings.
For example here's what I get:
Loading CSV from: (
(
Last,
First,
Middle,
Nickname,
Gender,
City,
Age,
Email
),
(
Doe,
John,
Awesome,
"JD",
M,
"San Francisco",
"20",
"john#john.doe"
),
How could I sort this into a Person object and filter through it using NSPredicate, like Mattt Thompson does here.
Here's how I initialize the parser:
//Prepare Roster
NSString *pathToFile = [[NSBundle mainBundle] pathForResource:#"myFile" ofType: #"csv"];
NSArray *myFile = [NSArray arrayWithContentsOfCSVFile:pathToFile options:CHCSVParserOptionsSanitizesFields];
NSLog(#"Loading CSV from: %#", myFile);
Here's what Mattt does in the article I linked, which I'd like to do with my code:
NSArray *firstNames = #[ #"Alice", #"Bob", #"Charlie", #"Quentin" ];
NSArray *lastNames = #[ #"Smith", #"Jones", #"Smith", #"Alberts" ];
NSArray *ages = #[ #24, #27, #33, #31 ];
NSMutableArray *people = [NSMutableArray array];
[firstNames enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
Person *person = [[Person alloc] init];
person.firstName = firstNames[idx];
person.lastName = lastNames[idx];
person.age = ages[idx];
[people addObject:person];
}];
First, define a suitable Person class:
#interface Person : NSObject
#property(copy, nonatomic) NSString *firstName;
#property(copy, nonatomic) NSString *lastName;
// ...
#property(nonatomic) int age;
// ...
#end
Then you can read your data into an array of Person objects by enumerating the
myFile array. Inside the block, row is the "sub-array" for a single row:
NSMutableArray *people = [NSMutableArray array];
[myFile enumerateObjectsUsingBlock:^(NSArray *row, NSUInteger idx, BOOL *stop) {
if (row > 0) { // Skip row # 0 (the header)
Person *person = [[Person alloc] init];
person.lastName = row[0];
person.firstName = row[1];
// ...
person.age = [row[6] intValue];
// ...
[people addObject:person];
}
}];
Now you can filter that array as shown in the tutorial:
NSPredicate *smithPredicate = [NSPredicate predicateWithFormat:#"lastName = %#", #"Smith"];
NSArray *filtered = [people filteredArrayUsingPredicate:smithPredicate];