lets say we have a simple array with file 1, file 2, file 3.
and we are displaying a controller with file 1, how can we write file 1 from the original array to a new and completely different array (lets call it different array).
NSArray *newArray = [NSArray arrayWithObject:[oldArray objectAtIndex:1]];
Edit: to answer the comment:
NSArray *bigArray = [NSArray arrayWithObjects:newArray1, newArray2, nil];
Now on a style note, you realize the first code line makes an array with only 1 object in it? there is really no need to create that array. you can simply reference the object you need from your original array, and if you wanted to put multiple objects into the bigArray you could. (You are creating an extra layer of NSArray that it doesn't look like is needed at all.)
Related
I have data collection(NSArray) of NSDictionary. Now in the app i need to show that data in three different sorting order. Now I do not want to make 3 different array (one for each sorting order with complete data) because it will consume memory nor I want to re-sort main array each time when user change sorting option.
so now my problem is, I want a mechanism that I can only get indexes of main array in 3 different array(or any other datatype) in 3 different sorting order. Should I have to do this manually or is there a build in method for geting sorted index array from main array?
What you're asking is impossible. You want to have your items sorted in 3 different orders without saving them into different arrays AND without sorting them every time the sorting method changes.
You can't get it for free. You can pay either with memory or with performance.
I'd go for memory, since it's not as costly as you think. Only the pointers to the NSDictionaries are kept in your array, so it shouldn't take too much memory.
NSArray takes only objects as its elements. And objects pointers are stored in the array. So I guess, the option you are talking about, saving indexes in another array is something similar like saving pointers in sorting order. So, you have create 3 different arrays with the pointers to objects in a particular order, it will be the same, not taking more memory. When you copy the sorted objects in new arrays, the objects will not be allocated again, only their pointers will be stored. However you have to do the sorting in right way.
If you want to keep your data in a single array, then you can use an NSMutableArray and (re-)sort it whenever the sort criteria changes.
Notice however that this means that if your data array is part of your model, and your sorting order is a presentation (UI) issue, then you are effectively mixing model, view and controller functionality in one object. Bad ( :-) ) but not the first time it has happened in history.
Here is an example using sort descriptors directly on keys of your dictionaries:
NSMutableArray *data = // ... your data as a mutable array
NSString* sortKey = // ... one of the 3 dictionary keys that you wish to sort by
NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:sortKey ascending:YES];
[data sortUsingDescriptors:#[sd]];
The data array is now sorted without using an extra array variable.
Step1 : Declare Enum Definition before import statement
enum COMP_TYPE {
LOCALIZE_COMPARE = 1,
CASE_INSENSITIVE = 2,
LOCALIZE_CASE_INSENSITIVE = 3
};
Step2 : Define following function in your .m file
-(NSArray *)sortArray:(NSArray *)arr WithType:(int)type andKey:(NSString *)key andOrder:(BOOL)order
{
SEL _compareSelector;
switch (type) {
case LOCALIZE_COMPARE:
_compareSelector = #selector(localizedCompare:);
break;
case CASE_INSENSITIVE:
_compareSelector = #selector(caseInsensitiveCompare:);
break;
case LOCALIZE_CASE_INSENSITIVE:
_compareSelector = #selector(localizedCaseInsensitiveCompare:);
break;
default:
break;
}
NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:key ascending:order selector:_compareSelector];
return [arr sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
}
Step3 : Declare your Array of Dictionary
NSArray *myArr = [NSArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:#"stack", #"name",
#"goa", #"name1",nil],
[NSDictionary dictionaryWithObjectsAndKeys:#"stack", #"name",
#"goa", #"name1",nil],
[NSDictionary dictionaryWithObjectsAndKeys:#"objective", #"name",
#"c++", #"name1",nil], nil];
Step4 : call function with diferent Parameter
NSLog(#"%#",[self sortArray:myArr WithType:LOCALIZE_COMPARE andKey:#"name" andOrder:YES]);
NSLog(#"%#",[self sortArray:myArr WithType:CASE_INSENSITIVE andKey:#"name" andOrder:YES]);
NSLog(#"%#",[self sortArray:myArr WithType:LOCALIZE_CASE_INSENSITIVE andKey:#"name" andOrder:YES]);
It is not possible to sort the same array for different orders.
You need to save the array each time before sorting.
i am displaying array of elements in a tableview.
Now i need to display some other new elements on table view.
For this i try by adding new elements to array which is datasource of table view and reloading the table.
Then It displaying the newly added elements but the problem is it is adding at last element of array so it displaying at the bottom of the table view.
But i need to display that new value at the top of the table view.
How can i done this can any one please help me.
Thank u in advance.
(Let me add comment if any one does n't get my question).
Insert the new items at the top of your array using NSMutableArray insertObject: atIndex:.
Create a new array with a capacity of the old array + n new objects. Add the new objects, then loop through the previous array and copy that into the new array. This way the first index - n-1 will have the items you added, therefore being displayed at the top of the table.
There may be an easier way to do this, but this implementation will definitely work.
Do you use arrayByAddingObjectsFromArray: to add new elements?
If so, the objects are added to the end of the original array, and thus displayed at the end of the table view.
So instead of adding new array to the end of the old array, how about adding old array to the end of the new array?
self.arrayForTable = [arrayWithNewElements arrayByAddingObjectsFromArray:arrayForTable];
If you are using NSMutableArray so there are many function available for inserting the new element at your desire place in array and they are ....
Inserts a given object into the array's contents at a given index.
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index
Inserts the objects in in a given array into the receiving array at the specified indexes.
- (void)insertObjects:(NSArray *)objects atIndexes:(NSIndexSet *)indexes
Below is the code from Apple Documentation ...
NSMutableArray *array = [NSMutableArray arrayWithObjects: #"one", #"two", #"three", #"four", nil];
NSArray *newAdditions = [NSArray arrayWithObjects: #"a", #"b", nil];
NSMutableIndexSet *indexes = [NSMutableIndexSet indexSetWithIndex:1];
[indexes addIndex:3];
[array insertObjects:newAdditions atIndexes:indexes];
NSLog(#"array: %#", array);
// Output: array: (one, a, two, b, three, four)
In the use case where you have an array of entities that need to be populated at that beginning of your existing data source, try the following:
-(NSMutableArray*)returnReorganizedArrayWithEarlierEntities:(NSArray*)theEarlierEntities{
theEarlierEntities = [[theEarlierEntities reverseObjectEnumerator] allObjects];
for(int i = 0; i < [theEarlierEntities count]; i++)
[dataSourceArray insertObject:[theEarlierEntities objectAtIndex:i] atIndex:0];
return dataSourceArray;
}
What this method does is reverse the order of the new entities you want added so that they are placed correctly (bottom-up) at the beginning of your existing data structure.
Cheers!
If you still want to use Array you can do this:
imagine we have an array whose type is your model(struct to class).
var yourArray = [YourModel]()
to add a new element on top of the array you can use
yourArray.insert(newElemet: Model, at: 0)
refer to this thread: Add an element to an array in Swift
My aim is to produce an array, which I can use to add section headers for a UITableView. I think the easiest way to do this, is to produce a sections array.
I want to create section headers for dates, where I'll have several or no rows for each.
So in my populate data array function, I want to populate a display array. So record 1, look for the first date in my display array, create a new array item if it doesn't exist, if it does exist add 1 to the count.
So I should end up with something like this.
arrDisplay(0).description = 1/June/2001; arrDisplay(0).value = 3;
arrDisplay(1).description = 2/June/2001; arrDisplay(1).value = 0;
arrDisplay(2).description = 3/June/2001; arrDisplay(2).value = 1;
arrDisplay(3).description = 5/June/2001; arrDisplay(3).value = 6;
My question is how do I create and use such an array with values, where I can add new elements of add to the count of existing elements and search for existing elements ?
I think, if i understand you, an NSMutableDictionary would work. (as NR4TR said) but, i think the object would be the description and the key would be the count. you could check for the key and get the count in the same gesture. if the return value of objectForKey is nil, it doesn't exist.
NSMutableDictionary *tableDictionary = [[NSMutableDictionary alloc] init];
NSString *displayKey = #"1/June/2001";
NSNumber *displayCount = [tableDictionary objectForKey:displayKey];
if (displayCount != nil) {
NSNumber *incrementedCount = [[NSNumber alloc] initWithInteger:[displayCount integerValue] + 1];
[tableDictionary removeObjectForKey:displayKey];
[tableDictionary setValue:incrementedCount
forKey:displayKey];
[incrementedCount release];
}
else {
NSNumber *initialCount = [[NSNumber alloc] initWithInteger:1];
[tableDictionary setValue:initialCount
forKey:displayKey];
[initialCount release];
}
EDIT: Hopefully this isn't pedantic, but I think a couple pointers will help.
Dictionaries, Sets, and Arrays all hold objects for retrieval. The manner of holding and retrieval desired drives the decision. I think of it based on the question 'what is the nature of the information that I have when I need an object being held?'
NSDictionary and NSMutableDictionary
Hold n objects per key. (I think...I haven't had to test a limit, but i know you can get an NSSet back as a value.)
KEY is more important than INDEX. I don't think of dictionaries as ordered. they know something and you need to ask the correct question.
NSArray and NSMutableArray
hold n objects in order.
INDEX is most important bit of information. (you can ask for the index of an object but, even here, the index is the important part)
you will typically drive table views with an array because the ordered nature of the array fits.
NSSet, NSMutableSet, and NSCountedSet
A collection of objects without order.
You can change any of these into the other with something like [nsset setFromArray:myArray];
and all of these things can hold the other as objects. I think an array as your top level is the correct thinking, but beyond that, it becomes an issue of implementation
Try array of dictionaries. Each dictionary contains two objects - section title and array of section rows.
If you want to have a description AND a rowcount then you can either create a class with those two properties and generate an NSArray of objects with that class or instead of all that you can just use an NSDictionary to store key/value lookups.
I think NSCountedSet is closest to what you want. It doesn't have an intrinsic order, but you can get an array out of it by providing a sort order.
I'm starting with iPhone development and I need to use a multidimensional array.
I initialize it using:
NSArray *multi=[NSArray
arrayWithObjects:[NSMutableArray arrayWithCapacity:13],
[NSMutableArray array],nil];
But when I try to assign values to n-th cell like this:
[[multi objectAtIndex:4] addObject:#"val"];
The app hangs because index 4 is beyond the bounds [0 .. 1].
Which is the correct way to init my multi-array? Thanks in advance and greetings.
I guess you want to create a NSMutableArray of NSMutableArrays:
NSMutableArray *multi = [NSMutableArray arrayWithCapacity: 13];
for (int i = 0; i != 13; i++)
{
NSMutableArray *array = [NSMutableArray arrayWithCapacity: 10];
[multi insertObject: array atIndex: 0];
}
After that, your call is valid.
EDIT: as a side note, capacity != count, as would be in .NET or C++'s STL if you know these.
What you did is creating an array containing two objects: two other arrays. You're actually asking for the 5th object within this "super-array", which won't work because there is none.
By the way, even if you create an array specifying a capacity, it is still empty. Specifying a capacity merely allocs enough memory for the array to hold at least the given number of objects. If you add no objects, it would still make your app crash if you'd ask for, say, the 10th object.
I have an array of strings that are comma separated such as:
Steve Jobs,12,CA
Fake Name,21,CA
Test Name,22,CA
Bill Gates,44,WA
Bill Nye,21,OR
I have those values in an NSScanner object so that I can loop through the values and get each comma seperated value using objectAtIndex.
So, what I would like to do, is group the array items into new arrays, based on a value, in this case, State. So, from those, I need to loop through, checking which state they are in, and push those into a new array, one array per state.
CA Array:
Steve Jobs,12,CA
Fake Name,21,CA
Test Name,22,CA
WA Array:
Bill Gates,44,WA
OR Array:
Bill Nye,21,OR
So in the end, I would have 3 new arrays, one for each state. Also, if there were additional states used in the first array, those should have new arrays created also.
Any help would be appreciated!
You can use a NSMutableDictionary of NSMutableArrays - if the state encountered isn't yet in the dictionary, add a new array.
NSMutableArray* arr = [states objectForKey:state];
if (arr == nil) {
arr = [NSMutableArray array];
[states setObject:arr forKey:state];
}
Then you can insert values into the array, preferably as objects though as Dave DeLong mentions.
You shouldn't be maintaining this data as CSV. That's asking for a world of hurt if you ever need to manipulate this data programmatically (such as what you're trying to do).
You can naïvely break this data up into an array using NSArray * portions = [line componentsSeparatedByString:#","];. Then create a custom object to store each portion (for an example, see this post), and then you can manipulate those objects almost effortlessly.
Naively: (assuming array of strings called strings)
NSMutableDictionary *states = [NSMutableDictionary dictionary];
for (NSString *string in strings) {
NSString *state = [[string componentsSeparatedByString:#", "] lastObject];
NSMutableArray *values = [states objectForKey:state];
if (values == nil) {
values = [NSMutableArray array];
[states setObject:value forKey:state];
}
[values addObject:string];
}
Number of things about this -- first of all, I'm not at my computer, so there is a high chance of typos and or things that I missed. Second, you probably want to adapt the components separated by string line to handle whitespace better.