objective c - how to get elements dynamically from NSArray? [closed] - ios

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have the json file below and I save it in an array by doing
NSArray *allFrames = [self.campaign.form.gameParams objectForKey:#"frames"];
What I want to achieve, is to place all the horizontal images from the url in a view. My problem is I want to do this dynamically, because the number of the elements may change.
frames = (
{
horizontal = "http://mysite.co.uk/files/frames/5_h.png";
vertical = "http://mysite.co.uk/files/frames/5_v.png";
},
{
horizontal = "http://mysite.co.uk/files/frames/6_h.png";
vertical = "http://mysite.co.uk/files/frames/6_v.png";
}
{
horizontal = "http://mysite.co.uk/files/frames/6_h.png";
vertical = "http://mysite.co.uk/files/frames/6_v.png";
}
);
What I have done until now is to store the urls statically like this
NSDictionary *frames = allFrames[0];
NSString * link1 = [frames objectForKey:#"horizontal"];
NSDictionary *frames = allFrames[1];
NSString * link2 = [frames objectForKey:#"horizontal"];
NSDictionary *frames = allFrames[2];
NSString * link3 = [frames objectForKey:#"horizontal"];
And then convert the urls into images
UIImage *webImage1 = [UIImage imageWithData:
[NSData dataWithContentsOfURL:
[NSURL URLWithString:link1]]];
etc
Any ideas how to do it?

Something like this?
NSMutableArray *imageArray = [[NSMutableArray alloc] init];
for (int i = 0; i < allFrames.count; i++) {
NSDictionary *dict = allFrames[i];
NSString *link = dict[#"horizontal"];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:link]]];
[imageArray addObject:image];
}

horizontal data can be filtered using valueForKey of NSArray.
NSArray *horizontalImages = [frames valueForKey:#"horizontal"];
for(NSString *urlString in horizontalImages)
{
UIImage *webImage1 = [UIImage imageWithData:
[NSData dataWithContentsOfURL:
[NSURL URLWithString: urlString]]];
}

NSArray *dict = #[#{#"horizontal": #"http://mysite.co.uk/files/frames/5_h.png"}, #{#"horizontal": #"http://mysite.co.uk/files/frames/6_h.png"}, #{#"horizontal": #"http://mysite.co.uk/files/frames/6_h.png"}];
NSMutableArray *horizontalLinks = [NSMutableArray array];
[dict enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[horizontalLinks addObject:[obj objectForKey:#"horizontal"]];
}];
NSLog(#"Horizontal Links: %#", horizontalLinks);
Will give you:
Horizontal Links: (
"http://mysite.co.uk/files/frames/5_h.png",
"http://mysite.co.uk/files/frames/6_h.png",
"http://mysite.co.uk/files/frames/6_h.png"
)

Related

Get substring from string variable and save to NSMutableArray [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am new to iOS development and facing some problem. I have a string like this M||100|??|L||150|??|S||50. I want to break the string into chunks and save to array, e.g M 100 is on 1st index, L 150 on second index, S 50 on third index.
NSString *str = #"M||100|??|L||150|??|S||50";
NSString *stringWithoutBars = [str stringByReplacingOccurrencesOfString:#"||" withString:#" "];
NSMutableArray *array = [[NSMutableArray alloc]initWithArray:[stringWithoutBars componentsSeparatedByString:#"|??|"]];
You can get Array from your string using this code
NSString *str = #"M||100|??|L||150|??|S||50";
str = [str stringByReplacingOccurrencesOfString:#"||" withString:#" "];
NSArray *array = [str componentsSeparatedByString:#"|??|"];
this will return your expected result.
let str = "M||100|??|L||150|??|S||50"
let array = str.componentsSeparatedByString("|??|")
print(array)
result :
["M||100", "L||150", "S||50"]
///First replace "||" with " "
NSString *your_str = #"M||100|??|L||150|??|S||50";
your_str = [your_str stringByReplacingOccurrencesOfString:#"||" withString:#" "];
///Get array of string
NSArray *arr = [your_str componentsSeparatedByString:#"|??|"];
NSMutableArray *data_arr = [[NSMutableArray alloc] init];
for(NSString *str in arr)
{
///string to data conversion
NSData *data = [your_str dataUsingEncoding:NSUTF8StringEncoding];
//////// add data to array
[data_arr addObject: data];
}
NSLog(#"data_arr =%#",data_arr);
NSString *str = #"M||100|??|L||150|??|S||50";
NSArray *arrt = [str componentsSeparatedByString:#"|??|"];
NSMutableArray *arr = [[NSMutableArray alloc]init];
for (int i = 0; i <= arrt.count - 1; i++) {
[arr addObject:[[arrt objectAtIndex:i] componentsSeparatedByString:#"||"]];
}

NSDictionary constant looping

SO I have a program which calls the FlickR API, gets the URL's puts them into a dictionary and then assigns them into a table view, using an image view.
NSArray *photos = [self.flickr photosForUser:#"James Kinvig"];
int countAttempts = 0;
[[self.flickr photosForUser:#"James Kinvig"]count];
for (int i = 0; i < [[self.flickr photosForUser:#"James Kinvig"]count]; i++) {
for(NSDictionary *dictionary in photos) {
countAttempts++;
NSString *farmId = [dictionary objectForKey:#"farm"];
NSString *serverId = [dictionary objectForKey:#"server"];
NSString *photoId = [dictionary objectForKey:#"id"];
NSString *secret = [dictionary objectForKey:#"secret"];
self.url= [NSURL URLWithString:[NSString stringWithFormat:#"http://farm%#.staticflickr.com/%#/%#_%#.jpg", farmId, serverId, photoId, secret]];
//NSLog(#"self.url = %#", self.url);
NSLog(#"count = %d", countAttempts);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSData *imgData = [NSData dataWithContentsOfURL:self.url];
dispatch_sync(dispatch_get_main_queue(), ^{
UIImage *img = [UIImage imageWithData:imgData];
cell.imageView.image = img;
[cell setNeedsLayout];
});
});
}
}
return cell;
}
This is the method it calls, photosForUser:
- (NSMutableArray *) photosForUser: (NSString *) friendUserName
{
NSString *request = [NSString stringWithFormat: #"https://api.flickr.com/services/rest/?method=flickr.people.findByUsername&username=%#", friendUserName];
NSDictionary *result = [self fetch: request];
NSString *nsid = [result valueForKeyPath: #"user.nsid"];
request = [NSString stringWithFormat: #"https://api.flickr.com/services/rest/?method=flickr.photos.search&per_page=%ld&has_geo=1&user_id=%#&extras=original_format,tags,description,geo,date_upload,owner_name,place_url", (long) self.maximumResults, nsid];
result = [self fetch: request];
return [result valueForKeyPath: #"photos.photo"];
}
Which does a fetch to the flickr API.
What is happening though is that is stuck in an eternal loop. Even with the for statement being less than the count, it still eternal loops. I have NSLog'd the count of the FlickR photos and it = 11.
This may have something to do with it, but whenever I press the button to take me to the table view controller, I get a HUGE lag, close to a minute, and nothing is being calculated (photo-wise) as I've done a count++
Thanks
let me understand this.. By the last line of your first block of code, I conclude that that is the uitableview dataSource method, cellForRowAtIndexPath.. what doesn't really makes sense.. you you have a fetch there, you have A loop inside a loop, that is setting many images (by download them) in one single imageView, and this is happening for all your visible cells at the same time. This will never work!
The solution is:
1 - remove this method from the cellForRow, this is not the place to request the images
2 - create another method that will fetch the content
3 - create a method that will do your loops and store the images on the array so you don't need to do that many times, only one..
4 - reload the tableview after you finish the step 3
5 - use the array of images that is already done to set your images by indexPath.row in your cell..
6 - I recommend you to use a Library for imageCache (i.e https://github.com/rs/SDWebImage)
NSArray *photos = [self.flickr photosForUser:#"James Kinvig"];
for (int i = 0; i < [[self.flickr photosForUser:#"James Kinvig"] count]; i++)
{
for (NSDictionary *dictionary in photos)
{
You have two nested loops iterating over the same collection. This turns what should be an O(n) operation into O(n^2) and explains why your process is taking a very long time.
Since the loop bodies never use i, I would fix it by getting rid of the outer loop:
NSArray *photos = [self.flickr photosForUser:#"James Kinvig"];
for (NSDictionary *dictionary in photos)
{

Remove items from array to ensure no duplicate strings [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I need to be able to pull 100's of strings from a plist and display them in a label within my project. I have managed to get this to work pulling data from two different arrays within my plist and then generating a random string to display.
What i want to do now is ensure that no two strings are displayed twice in one session and also be able to set a counter system up that after 5 goes it displays a message.
I was thinking of doing a simple counter for the display message after x amount of turns however when it comes to not displaying duplicates from the array im a little lost. I need it to only basically remove an item from the array (not the plist every time the user presses the button)
- (IBAction)truth:(id)sender {
NSString *path = [[NSBundle mainBundle] pathForResource:
#"test" ofType:#"plist"];
NSDictionary *plistDict = [[NSDictionary alloc] initWithContentsOfFile:path];
NSMutableArray *plistArray = plistDict[#"truth"];
NSDictionary *plistDict2 = [[NSDictionary alloc] initWithContentsOfFile:path];
NSMutableArray *plistArray2 = plistDict2[#"dare"];
plistArray = [plistArray arrayByAddingObjectsFromArray:plistArray2];
NSLog(#"%#", plistArray);
int randV = arc4random() % plistArray.count;
self.joke.text = plistArray[randV];
NSLog(#"dictionary: %#, array: %#", plistDict, plistArray);
}
The problem you have is that every time you are getting a message, you are reading the plists again and recreating plistArray
The correct way would be to save plistArray into a local variable (a property) and only populate it the first time.
Then, if you want to remove an item, you call `[plistArray removeObjectAtIndex: randV];
Edit: code
// In .h file
#property (strong, nonatomic) NSMutableArray * plistArray;
- (IBAction)truth:(id)sender {
if (!self.plistArray) {
NSString *path = [[NSBundle mainBundle] pathForResource:
#"test" ofType:#"plist"];
NSDictionary *plistDict = [[NSDictionary alloc] initWithContentsOfFile:path];
NSArray * plistArray1 = plistDict[#"truth"];
NSDictionary *plistDict2 = [[NSDictionary alloc] initWithContentsOfFile:path];
NSArray *plistArray2 = plistDict2[#"dare"];
self.plistArray = [[plistArray1 arrayByAddingObjectsFromArray:plistArray2] mutableCopy];
}
NSLog(#"%#", plistArray);
int randV = arc4random() % self.plistArray.count;
self.joke.text = self.plistArray[randV];
[self.plistArray removeObjectAtIndex:randV];
NSLog(#"dictionary: %#, array: %#", plistDict, self.plistArray);
}
#property
Create an NSMutableSet from plistArray and each time you retrieve one remove it from the set. Presto!
EDIT: Add code
NSMutableSet *jokes = [[NSMutableSet alloc] initWithArray:plistArray];
NSString *joke = [jokes anyObject];
[jokes removeObject:joke];
Disclaimer: As the documentation says, anyObject is not guaranteed to be random. I believe you can work something out for yourself here. E.g.
NSString *joke = [[jokes allObjects] objectAtIndex:arc4random() % [jokes count]];
[plistArray removeObjectAtIndex: randV];

Can't store all data from NSArray into NSMutableDictionary? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
What's the problem with this code?? I am trying to put the data from an NSArray to a NSMutableDictionary but I do not want to first split the initial nsarray into two and then send the data to the nsdcitionary.
The problem is that when I NSLog de mutabledictionary it returns me just the 1 item which happens to be the last data from the NSArray.
NSString *str = #"13:00,2.00,13:05,2.03,13:10,2.07,13:15,2.01,13:20,2.08,13:25,2.10,13:30,2.15";
NSArray *arrayFinal = [str componentsSeparatedByString:#","];
NSMutableDictionary *dict = [NSMutableDictionary new];
for (int i = 0; i < [arrayFinal count ]; i = i + 2) {
[dict setObject:[arrayFinal objectAtIndex:i] forKey:#"hora"];
[dict setObject:[arrayFinal objectAtIndex:i+1] forKey:#"preco"];
}
The result is:
2013-09-04 20:27:33.732 separa[1438:c07] {
hora = "13:30";
preco = "2.15";
}
Any help will be appreciated.
for (int i = 0; i < [arrayFinal count ]; i = i + 2) {
[dict setObject:[arrayFinal objectAtIndex:i+1] forKey:[arrayFinal objectAtIndex:i]];
}
You need each key to point to an array of values. Something like this:
NSString *str = #"13:00,2.00,13:05,2.03,13:10,2.07,13:15,2.01,13:20,2.08,13:25,2.10,13:30,2.15";
NSArray *arrayFinal = [str componentsSeparatedByString:#","];
NSMutableArray *horas = [NSMutableArray new];
NSMutableArray *precos = [NSMutableArray new];
for (int i = 0; i < [arrayFinal count]; i += 2) {
[horas addObject:arrayFinal[i]];
[precos addObject:arrayFinal[i + 1]];
}
NSMutableDictionary *dict = [NSMutableDictionary new];
dict[#"hora"] = horas;
dict[#"preco"] = precos;
You're going to need to separate the two (hours and prices) into their own NSMutableArrays, then store each array as one of the keys, something like this:
NSMutableArray *hora = [NSMutableArray alloc] init];
NSMutableArray *preco = [NSMutableArray alloc] init];
NSString *str = #"13:00,2.00,13:05,2.03,13:10,2.07,13:15,2.01,13:20,2.08,13:25,2.10,13:30,2.15";
NSArray *arrayFinal = [str componentsSeparatedByString:#","];
NSMutableDictionary *dict = [NSMutableDictionary alloc] init];
for (int i = 0; i < [arrayFinal count ]; i = i + 2)
{
[hora addObject:[arrayFinal objectAtIndex:i];
[preco addObject:[arrayFinal objectAtIndex:i+1];
}
[dict setObject:hora forKey:#"hora"];
[dict setObject:preco forKey:#"preco"];
Probably not exactly the way I'd do it, but I think it is the concept you're looking for.

Separate two strings from one array element

I was wondering if anyone could lend some assistance. Basically I am calling a web service and then trying to get the large hosted image url. The output from the web service is so:
images = (
{
hostedLargeUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.l.jpg";
hostedSmallUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.s.jpg";
}
);
The main problem is that the two strings are in only one of my array elements when I think they should be in 2. Also I'm not 100% but possibly they may be a dictionary :-S I'm just not sure. My code is as follows:
NSArray *imageArray = [[NSArray alloc]init];
imageArray = [self.detailedSearchYummlyRecipeResults objectForKey:#"images"];
NSLog(#"imageArray: %#", imageArray);
NSLog(#"count imageArray: %lu", (unsigned long)[imageArray count]);
NSString *hostedLargeurlString = [imageArray objectAtIndex:0];
NSLog(#"imageArrayString: %#", hostedLargeurlString);
The output (nslog's) from the above code is:
2013-04-28 18:59:52.265 CustomTableView[2635:11303] imageArray: (
{
hostedLargeUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.l.jpg";
hostedSmallUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.s.jpg";
}
)
2013-04-28 18:59:52.266 CustomTableView[2635:11303] count imageArray: 1
2013-04-28 18:59:52.266 CustomTableView[2635:11303] imageArrayString: {
hostedLargeUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.l.jpg";
hostedSmallUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.s.jpg";
}
Does anyone have any idea how I can seperate the one element into hostedlargeUrl and hostedsmallUrl respectively?
Any help you can provide is greatly appreciated!
Actually the images array contains a dictionary
images = (
{
hostedLargeUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.l.jpg";
hostedSmallUrl = "http://i.yummly.com/Crispy-roasted-chickpeas-_garbanzo-beans_-308444.s.jpg";
}
);
so :
NSDictionary *d = [self.detailedSearchYummlyRecipeResults objectForKey:#"images"][0];
NSString *largeURL = d[#"hostedLargeUrl"];
NSString *smallURL = d[#"hostedSmallUrl"];
The value of [imageArray objectAtIndex:0] is a NSDictionary. You've incorrectly specified it as a NSString. You need the following:
NSDictionary *hostedLarguerDictionary =
(NSDictionary *) [imageArray objectAtIndex:0];
and then to access the 'large url' use:
hostedLarguerDictionary[#"hostedLargeUrl"]
or, equivalently
[hostedLarguerDictionary objectForKey: #"hostedLargeUrl"];
looks like an array with in an array so
NSArray* links = [self.detailedSearchYummlyRecipeResults objectForKey:#"images"];
NSString* bigLink = [links objectAtIndex:0];
NSString* smallLink = [links objectAtIndex:1];
or it could be a dictionary
NSDictionary* links = [self.detailedSearchYummlyRecipeResults objectForKey:#"images"];
NSString* bigLink = [links objectForKey:#"hostedLargeUrl "];
NSString* smallLink = [links objectForKey:#"hostedSmallUrl "];
you can see the class of the object by printing out the class name
NSLog(#"Class Type: %#", [[self.detailedSearchYummlyRecipeResults objectForKey:#"images"] class]);

Resources