i am new to ios and i am really stuck at finding solution for this...
animals = #{#"B" : #[#"Bear", #"Black Swan", #"Buffalo"],
#"C" : #[#"Camel", #"Cockatoo"],
#"D" : #[#"Dog", #"Donkey"],
#"E" : #[#"Emu"],
#"G" : #[#"Giraffe", #"Greater Rhea"],
#"H" : #[#"Hippopotamus", #"Horse"],
#"K" : #[#"Koala"],
#"L" : #[#"Lion", #"Llama"],
#"M" : #[#"Manatus", #"Meerkat"],
#"P" : #[#"Panda", #"Peacock", #"Pig", #"Platypus", #"Polar Bear"],
#"R" : #[#"Rhinoceros"],
#"S" : #[#"Seagull"],
#"T" : #[#"Tasmania Devil"],
#"W" : #[#"Whale", #"Whale Shark", #"Wombat"]};
animalSectionTitles = [[animals allKeys] sortedArrayUsingSelector:#selector(compare:)];
the code above doesn't error but when i trying to insert array into NSDictionary, it always shows unrecognized selecter. What should i do to solve this problem?
while (sqlite3_step(statement)==SQLITE_ROW) {
Word *univer = [[Word alloc] init];
univer.Id =[NSString stringWithUTF8String:(char *) sqlite3_column_text(statement,0)];
univer.word=[NSString stringWithUTF8String:(char *) sqlite3_column_text(statement,1)];
//NSLog(#"%#",univer.word);
NSString *first = [univer.word substringToIndex:1];
NSLog(#"%#",first);
if([first isEqualToString:#"A"] || [first isEqualToString:#"a"]){
[_A addObject:univer.word];
}
else if([first isEqualToString:#"B"] || [first isEqualToString:#"b"]){
[_B addObject:univer.word];
}
else if([first isEqualToString:#"C"] || [first isEqualToString:#"c"]){
[_C addObject:univer.word];
}
else if([first isEqualToString:#"D"] || [first isEqualToString:#"d"]){
[_D addObject:univer.word];
}
else if([first isEqualToString:#"E"] || [first isEqualToString:#"e"]){
[_E addObject:univer.word];
}
else if([first isEqualToString:#"F"] || [first isEqualToString:#"f"]){
[_F addObject:univer.word];
}
else if([first isEqualToString:#"G"] || [first isEqualToString:#"g"]){
[_G addObject:univer.word];
}
else if([first isEqualToString:#"H"] || [first isEqualToString:#"h"]){
[_H addObject:univer.word];
}
}
animals= [NSDictionary dictionaryWithObjectsAndKeys:_A,_B,_C,_D,_E,_F,_G,_H, nil];
animalSectionTitles = [[animals allKeys] sortedArrayUsingSelector:#selector(compare:)];
The problem is this line:
animals= [NSDictionary dictionaryWithObjectsAndKeys:_A,_B,_C,_D,_E,_F,_G,_H, nil];
When you create a dictionary with dictionaryWithObjectsAndKeys: the list of items you supply have to be objectA, keyA, objectB, keyB, objectC, keyC, nil. Right now it looks like all you have is objectA, objectB, objectC, nil. Which looks like this if you write it out:
animals = #{#[#"Bear", #"Black Swan", #"Buffalo"] : #[#"Camel", #"Cockatoo"],
#[#"Dog", #"Donkey"] : #[#"Emu"],
#[#"Giraffe", #"Greater Rhea"] : #[#"Hippopotamus", #"Horse"]};
When you call [[animals allKeys] sortedArrayUsingSelector:#selector(compare:)] it's calling the compare: selector on all of the items in [animals allKeys] which are NSArrays which don't support the compare: method and thus the unrecognized selector error.
Not sure exactly what you want but try this:
animals= [NSDictionary dictionaryWithObjectsAndKeys:_A, #"A", _B, #"B", _C, #"C", nil];
Related
hello i am new to IOS dev, and i need to create the contacts like view, i was able to create it if i already have the arrays of contacts and indexes, but what i need is the get the contacts from the server and sort them with indexes with objective C, any help?
i checked this tutorial:
animals = #{#"B" : #[#"Bear", #"Black Swan", #"Buffalo"],
#"C" : #[#"Camel", #"Cockatoo"],
#"D" : #[#"Dog", #"Donkey"],
#"E" : #[#"Emu"],
#"G" : #[#"Giraffe", #"Greater Rhea"],
#"H" : #[#"Hippopotamus", #"Horse"],...
sectionTitles = [[animals allKeys] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
animalIndexTitles = #[#"A", #"B", #"C", #"D", #"E", #"F", #"G", #"H", #"I", #"J", #"K", #"L", #"M", #"N", #"O", #"P", #"Q", #"R", #"S", #"T", #"U", #"V", #"W", #"X", #"Y", #"Z"];
but obviously this isn't what i need,
First you have to sort all keys :
NSArray *keys = [animals allKeys];
NSArray *sortedKeys = [keys sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSString *first = [someDictionary objectForKey:a];
NSString *second = [someDictionary objectForKey:b];
return [first compare:second];
}];
after sorting keys you have to sort each array against keys .
for( i= 0 ; i < [sortedKeys count ]; i++){
NSArray * arr = [animals objectForKey:[sortedKeys objectAtIndex: i] ];
NSArray *sortedArray = [arr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [[obj1 valueForKey:#"value"] compare:[obj2 valueForKey:#"value"]];
}];
As mentioned here is possible with swift to How to group by the elements of an array : How to group by the elements of an array in Swift using this extension :
public extension SequenceType {
/// Categorises elements of self into a dictionary, with the keys given by keyFunc
func categorise<U : Hashable>(#noescape keyFunc: Generator.Element -> U) -> [U:[Generator.Element]] {
var dict: [U:[Generator.Element]] = [:]
for el in self {
let key = keyFunc(el)
if case nil = dict[key]?.append(el) { dict[key] = [el] }
}
return dict
}
}
How to do the same with Objective C
Same results in Objective C. I tried this for your question and I got the solution now.It works fine.
NSArray *array = #[#{#"name" : #"lunch", #"date" : #"01-01-2015" , #"hours" : #"1"},
#{#"name" : #"dinner", #"date" : #"01-01-2015" , #"hours" : #"1"},
#{#"name" : #"dinner", #"date" : #"01-01-2015" , #"hours" : #"1"},
#{#"name" : #"lunch", #"date" : #"01-01-2015" , #"hours" : #"1"},
#{#"name" : #"dinner", #"date" : #"01-01-2015" , #"hours" : #"1"},
];
NSMutableArray *resultLunchArray = [NSMutableArray new];
NSMutableArray *resultDinnerArray = [NSMutableArray new];
NSMutableArray *finalResultsArray = [NSMutableArray new];
NSArray *groupLunch = [array valueForKeyPath:#"#distinctUnionOfObjects.name"];
for (NSString *str in groupLunch)
{
NSArray *groupNames = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"name = %#", str]];
if([str isEqualToString:#"lunch"])
{
for (int i = 0; i < groupNames.count; i++)
{
NSString *nameLunch = [[groupNames objectAtIndex:i] objectForKey:#"name"];
NSString *dateLunch = [[groupNames objectAtIndex:i] objectForKey:#"date"];
NSString *strNameLunch = [NSString stringWithFormat:#"%# : %#",nameLunch,dateLunch];
[resultLunchArray addObject:strNameLunch];
}
[finalResultsArray addObject:resultLunchArray];
}
else{
for (int i = 0; i < groupNames.count; i++)
{
NSString *nameDinner = [[groupNames objectAtIndex:i] objectForKey:#"name"];
NSString *dateDinner = [[groupNames objectAtIndex:i] objectForKey:#"date"];
NSString *strNameDinner = [NSString stringWithFormat:#"%# : %#",nameDinner,dateDinner];
[resultDinnerArray addObject:strNameDinner];
}
[finalResultsArray addObject:resultDinnerArray];
}
}
NSLog(#"The final results are - %#",finalResultsArray);
The Output Reults are
The final results are - (
(
"lunch : 01-01-2015",
"lunch : 01-01-2015"
),
(
"dinner : 01-01-2015",
"dinner : 01-01-2015",
"dinner : 01-01-2015"
)
)
i have an array with 12 sections and i need to replace value at index.
My test code:
NSMutableArray *hm = [[NSMutableArray alloc] initWithObjects:#{#"first": #[#"test1", #"test2"]}, #{#"second": #[#"test1"]}, nil];
NSLog(#"%#", [hm valueForKey:#"first"][0][0] );
[[hm valueForKey:#"first"][0] replaceObjectAtIndex:0 withObject:#"lol"];
NSLog(#"%#", hm);
First NSLog returns : test1 - its ok
When replace - crash with -[__NSArrayI replaceObjectAtIndex:withObject:]: unrecognized selector sent to instance 0x7fde53d2f700
I need to change test1 to something.
Wha am i doing wrong please?
NSMutableArray *hm = [[NSMutableArray alloc] initWithObjects:#{#"first": #[#"test1", #"test2"]}, #{#"second": #[#"test1"]}, nil];
NSLog(#"%#", [hm valueForKey:#"first"][0][0] );
//Your inner array is immutable, change it to mutable and replace the object, That's it.
NSMutableArray *array = [[hm valueForKey:#"first"][0] mutableCopy];
[array replaceObjectAtIndex:0 withObject:#"lol"];
[hm replaceObjectAtIndex:0 withObject:array];
NSLog(#"%#", hm);
NSMutableArray *arr = [[NSMutableArray alloc] initwithArray[[hm objectAtIndex:0]objectForKey:#"first"]];
[arr replaceObjectAtIndex:0 withObject:#"lol"];
[hm replaceObjectAtIndex:0 withObject:arr];
You have to make mutable dictionary and array structure
NSMutableArray* names = [NSMutableArray arrayWithObjects:
[NSMutableDictionary dictionaryWithObjectsAndKeys:
#"Joe",#"firstname",
#"Bloggs",#"surname",
nil],
[NSMutableDictionary dictionaryWithObjectsAndKeys:
#"Simon",#"firstname",
#"Templar",#"surname",
nil],
[NSMutableDictionary dictionaryWithObjectsAndKeys:
#"Amelia",#"firstname",
#"Pond",#"surname",
nil],
nil];
NSLog(#"Before - %#",names);
[names replaceObjectAtIndex:0 withObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
#"Joe_New",#"firstname",
#"Bloggs_New",#"surname",
nil]];
NSLog(#"After - %#",names);
Before - (
{
firstname = Joe;
surname = Bloggs;
},
{
firstname = Simon;
surname = Templar;
},
{
firstname = Amelia;
surname = Pond;
}
)
After - (
{
firstname = "Joe_New";
surname = "Bloggs_New";
},
{
firstname = Simon;
surname = Templar;
},
{
firstname = Amelia;
surname = Pond;
}
)
NSMutableArray *hm = [[NSMutableArray alloc] initWithObjects:#{#"first": #[#"test1", #"test2"]}, #{#"second": #[#"test1"]}, nil];
NSMutableDictionary *dic=[[NSMutableDictionary alloc] initWithDictionary:[hm objectAtIndex:0]];
NSMutableArray *array=[NSMutableArray arrayWithArray:[dic objectForKey:#"first"]];
[array replaceObjectAtIndex:0 withObject:#"lol"];
[dic setObject:array forKey:#"first"];
[hm replaceObjectAtIndex:0 withObject:array];
O/P (ViewController.m:48) (
(
lol,
test2
),
{
second = (
test1
);
}
)
I want to use -[NSArray componentsJoinedByString] with some condition for example : concatenate all elements of my array with ", " except the last one where I want an " and ".
It python it would be something like :
', '.join(array[:-1]) + ' and ' + array[-1]
Is there a way or a method that would do the trick in one line, avoiding all the if else stuff ?
You can use subarrayWithRange: and stringWithFormat: to do the same thing. You do need at least 1 if to check the count of items in the array and ensure that you don't have an index exception.
try like this,i dont know is this effiecient or not but check once,
NSArray *arr= [[NSArray alloc]initWithObjects:#"1",#"2",#"3", nil];
NSString *string = [arr componentsJoinedByString:#","];
NSString *str= [NSString stringWithFormat:#"%# and %#",[string substringToIndex:[string length]-[[arr lastObject] length]-1],[arr lastObject]];
NSLog(#"%#",str);
It might not be the most efficient, but it is a nice simple solution to take an array of objects that have string representations and turn them into a comma separated list such as 1, 2, 3, and 4.
#implementation NSArray (MyCollection)
- (NSString *)stringCommaAndSeparated
{
return [self stringCommaAndSeparatedUsingStringConverter:^NSString *(id object) {
assert( [object isKindOfClass:NSString.class] );
return (NSString *)object;
}];
}
- (NSString *)stringCommaAndSeparatedUsingStringConverter:(NSString *(^)(id object))stringConverter
{
assert( stringConverter );
if( self.count == 0 )
return #"";
if( self.count == 1 )
return stringConverter(self.firstObject);
if( self.count == 2 )
return [NSString stringWithFormat:NSLocalizedString(#"%# and %#", nil), stringConverter(self[0]), stringConverter(self[1]) ];
NSMutableString *string = [[NSMutableString alloc] init];
for( int index = 0; index < self.count-1; index += 1 )
[string appendFormat:NSLocalizedString(#"%#, ", nil), stringConverter(self[index])];
[string appendFormat:NSLocalizedString(#"and %#", nil), stringConverter(self.lastObject)];
return string; // This is returning a mutable string, but we could copy it to an immutable one!
}
#end
Here is an example of this in action:
// Results in #"1, 2, 3, and 4"
NSString *str = [#[#"1", #"2", #"3", #"4"] stringCommaAndSeparated];
// Results in #"1, 2, 3, and 4"
NSString *str2 = [#[#(1), #(2), #(3), #(4)] stringCommaAndSeparatedUsingStringConverter:^NSString *(id object) {
assert( [object isKindOfClass:NSNumber.class] );
NSNumber *number = object;
return number.stringValue;
}];
Here's my category solution, based on Wain's answer:
#implementation NSArray (NSString)
- (NSString *)listStringUsingLocale:(NSLocale *)locale
{
if(!self.count)
return nil;
if(!locale)
locale = [NSLocale currentLocale];
NSString *language = [locale objectForKey: NSLocaleLanguageCode];
if([language isEqualToString:#"en"])
{
if (self.count > 1)
{
NSArray *arr1 = [self subarrayWithRange:NSMakeRange(0, self.count - 1)];
return [NSString stringWithFormat:#"%# and %#", [arr1 componentsJoinedByString:#", "], self.lastObject];
}
else
{
return self[0];
}
}
return nil;
}
#end
I've added the option to add locale-based options.
What I've done so far to make a search bar work...
- (void)viewDidLoad
{
[self makeData];
[super viewDidLoad];
self.mySearchBar.delegate = self;
self.myTableView.delegate = self;
self.myTableView.dataSource = self;
//Feedback button code here
UIBarButtonItem *feedback;
feedback = [[UIBarButtonItem alloc] initWithTitle:#"Contact" style:UIBarButtonItemStylePlain
target:self action:#selector(showEmail:)];
self.navigationItem.leftBarButtonItem = feedback;
[self.tableView reloadData];
self.tableView.scrollEnabled = YES;
}
-(void) makeData; {
list = [[NSMutableArray alloc] init];
[list addObject:[[NSMutableDictionary alloc]
initWithObjectsAndKeys:#"Acceleration", #"name" ,
#"acceleration.png", #"image" ,
#"Acceleration", #"description" ,nil]];
[list addObject:[[NSMutableDictionary alloc]
initWithObjectsAndKeys:#"Alternating Current", #"name" ,
#"alternating current.png", #"image" ,
#"Alternating Current", #"description" ,nil]];
[list addObject:[[NSMutableDictionary alloc]
initWithObjectsAndKeys:#"Ampere", #"name" ,
#"ampere.png", #"image" ,
#"Ampere", #"description" ,nil]];
[list addObject:[[NSMutableDictionary alloc]
initWithObjectsAndKeys:#"Amplitude", #"name" ,
#"amplitude.png", #"image" ,
#"Amplitude", #"description" ,nil]];
}
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
if (searchText.length == 0) {
isFiltered = FALSE;
}
else
{
isFiltered = TRUE;
filteredList = [[NSMutableArray alloc] init];
for (NSString *str in list) {
NSRange stringRange = [str rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (stringRange.location != NSNotFound) {
[filteredList addObject:str];
}
}
}
[self.myTableView reloadData];
}
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[self.myTableView reloadData];
}
Yet each time I try to type something in the app crashes and I get this message:
2013-05-29 11:36:09.734 PhysEX[4770:c07] -[__NSDictionaryM rangeOfString:options:]: unrecognized selector sent to instance 0x9468cd0
2013-05-29 11:36:09.735 PhysEX[4770:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryM rangeOfString:options:]: unrecognized selector sent to instance 0x9468cd0'
How do I get my search to work?
The following piece of code in textDidChange delegate is not correct:
for (NSString *str in list) {
...
}
It is because objects in the list array are not NSString but NSDictionary. Hence the error message saying that NSDictionary does not recognize the selector rangeOfString:options: because that selector is for NSString instance.
You need to search through NSDictionary values instead.
for (NSDictionary *theDictionary in list) {
for (NSString *key in theDictionary) {
NSString *value = [theDictionary objectForKey:key];
NSRange stringRange = [value rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (stringRange.location != NSNotFound) {
[filteredList addObject:theDictionary];
break;
}
}
}