How to pair strings together from NSArray? [duplicate] - objective-c

This question already has answers here:
split array of objects into groups of 4 - ios
(3 answers)
Closed 1 year ago.
I have a NSArray that looks like this:
NSArray *array = {#"1.100.2", #"23465343", #"1.100.1", #"46535334", #"1.0.03", #"24353454" ...};
I need to pair every 2 strings into an array within an array like this:
NSArray *pairedArray = {{#"1.100.2", #"23465343"}, {#"1.100.1", #"46535334"}, {#"1.0.03", #"24353454"}, ...};
The array is dynamic.
I think there's a for statement I can use but can't remember. Something like for (uint i = 0; i < len - 1; i += 2)
Any help would be appreciated.

Here is something that tries to be fast, by using the array's iterator and by making heavy use of arrayWithCapacity.
NSArray *array = #[ #"1.100.2", #"23465343", #"1.100.1", #"46535334", #"1.0.03", #"24353454" ];
NSUInteger countPerPair = 2;
NSMutableArray * pair = [NSMutableArray arrayWithCapacity:countPerPair];
NSMutableArray * pairedArray = [NSMutableArray arrayWithCapacity:( array.count + countPerPair / 2 ) / countPerPair];
for ( NSObject * i in array )
{
if ( pair.count == countPerPair )
{
[pairedArray addObject:pair];
pair = [NSMutableArray arrayWithCapacity:countPerPair];
}
[pair addObject:i];
}
if ( pair.count )
{
[pairedArray addObject:pair];
}

Related

Flatten an NSArray

I have an array like this:
array: (
(
"http://aaa/product/8_1371121323.png",
"http://aaa/product/14_1371123271.png"
),
(
"http://aaa/product/9_1371121377.png"
)
)
and I have to create another array from that one like this
array: (
"http://aaa/product/8_1371121323.png",
"http://aaa/product/14_1371123271.png",
"http://aaa/product/9_1371121377.png"
)
How can I do that? Is it possible to combine all the objects and separate them using some string?
It can be done in a single line if you like key-value coding (KVC). The #unionOfArrays collection operator does exactly what you are looking for.
You may have encountered KVC before in predicates, bindings and similar places, but it can also be called in normal Objective-C code like this:
NSArray *flatArray = [array valueForKeyPath: #"#unionOfArrays.self"];
There are other collection operators in KVC, all prefixed with an # sign, as discussed here.
Sample Code :
NSMutableArray *mainArray = [[NSMutableArray alloc] init];
for (int i = 0; i < bigArray.count ; i++)
{
[mainArray addObjectsFromArray:[bigArray objectAtIndex:i]];
}
NSLog(#"mainArray :: %#",mainArray);
Sample code:
NSArray* arrays = #(#(#"http://aaa/product/8_1371121323.png",#"http://aaa/product/14_1371123271.png"),#(#"http://aaa/product/9_1371121377.png"));
NSMutableArray* flatArray = [NSMutableArray array];
for (NSArray* innerArray in arrays) {
[flatArray addObjectsFromArray:innerArray];
}
NSLog(#"%#",[flatArray componentsJoinedByString:#","]);
NSMutableArray *arr1 = [NSMutableArray arrayWithArray:[initialArray objectAtIndex:0]];
[arr1 addObjectsFromArray:[initialArray objectAtIndex:1]];
Now arr1 contains all the objects

UIButton with random text/value or tag [duplicate]

This question already has answers here:
iOS: How do I generate 8 unique random integers?
(6 answers)
Closed 9 years ago.
I have 10 UIButtons created in historyboard, OK?
I want to add random numbers that do not repeat these numbers, ie, numbers from 0 to 9 that interspersed whenever the View is loaded.
I tried to find on Google and here a way to use my existing buttons ( 10 UIButton ), and just apply them to random values​​. Most ways found ( arc4random() % 10 ), repeat the numbers.
Here's one
here's another
here's another
All results found that creating buttons dynamically. Anyone been through this?
Create an array of the numbers. Then perform a set of random swapping of elements in the array. You now have your unique numbers in random order.
- (NSArray *)generateRandomNumbers:(NSUInteger)count {
NSMutableArray *res = [NSMutableArray arrayWithCapacity:count];
// Populate with the numbers 1 .. count (never use a tag of 0)
for (NSUInteger i = 1; i <= count; i++) {
[res addObject:#(i)];
}
// Shuffle the values - the greater the number of shuffles, the more randomized
for (NSUInteger i = 0; i < count * 20; i++) {
NSUInteger x = arc4random_uniform(count);
NSUInteger y = arc4random_uniform(count);
[res exchangeObjectAtIndex:x withObjectAtIndex:y];
}
return res;
}
// Apply the tags to the buttons. This assumes you have 10 separate ivars for the 10 buttons
NSArray *randomNumbers = [self generateRandomNumbers:10];
button1.tag = [randomNumbers[0] integerValue];
button2.tag = [randomNumbers[1] integerValue];
...
button10.tag = [randomNumbers[9] integerValue];
#meth has the right idea. If you wanna make sure the numbers aren't repeating, try something like this: (note: top would the highest number to generate. Make sure this => amount or else this will loop forever and ever and ever ;)
- (NSArray*) makeNumbers: (NSInteger) amount withTopBound: (int) top
{
NSMutableArray* temp = [[NSMutableArray alloc] initWithCapacity: amount];
for (int i = 0; i < amount; i++)
{
// make random number
NSNumber* randomNum;
// flag to check duplicates
BOOL duplicate;
// check if randomNum is already in your array
do
{
duplicate = NO;
randomNum = [NSNumber numberWithInt: arc4random() % top];
for (NSNumber* currentNum in temp)
{
if ([randomNum isEqualToNumber: currentNum])
{
// now we'll try to make a new number on the next pass
duplicate = YES;
}
}
} while (duplicate)
[temp addObject: randomNum];
}
return temp;
}

Objective-C Version comparison [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Comparing version numbers
How to use compare on a version number where theres less parts in one number in Objective-C?
I am attempting to sort an NSMutableArray of custom objects based on a property called referenceID which essentially resembles a version number.
It seems that treating referenceID as an NSNumber and sorting it using compareTo: almost gets it right, but where it breaks is cases such as:
Result: Should Be:
1.1.1 1.1.1
1.1.10 1.1.2
1.1.2 ...
... 1.1.9
1.1.9 1.1.10
(Where ... is 1.1.2 through 1.1.9)
Are there any built in functions that will sort this properly? Or should I get started writing the sorting algorithm?
If your reference id is a string, you can use localizedStandardCompare:, which compares numbers in strings according to their numerical value.
Example (with sortedArrayUsingComparator, because that is used by the OP in his comment):
NSArray *versions = #[#"2.1.1.1", #"2.10.1", #"2.2.1"];
NSArray *sorted = [versions sortedArrayUsingComparator:^NSComparisonResult(NSString *s1, NSString *s2) {
return [s1 localizedStandardCompare:s2];
}];
NSLog(#"%#", sorted);
Output:
2012-11-29 23:51:28.962 test27[1962:303] (
"2.1.1.1",
"2.2.1",
"2.10.1"
)
sort it with a block
#autoreleasepool {
//in this example, array of NSStrings
id array = #[#"1.1.1",#"2.2",#"1.0",#"1.1.0.1",#"1.1.2.0", #"1.0.3", #"2.1.1.1", #"2.1.1", #"2.1.10"];
//block
id sorted = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSArray *comps1 = [obj1 componentsSeparatedByString:#"."];
NSArray *comps2 = [obj2 componentsSeparatedByString:#"."];
//get ints from comps
int res1 = 0;
for (int i=0; i<comps1.count; i++) {
res1 += [comps1[i] intValue] * (4 - i);
}
int res2 = 0;
for (int i=0; i<comps2.count; i++) {
res2 += [comps2[i] intValue] * (4 - i);
}
return res1<res2 ? NSOrderedAscending : res1>res2 ? NSOrderedSame : NSOrderedDescending;
}];
NSLog(#"%#", sorted);
}

How to pick a smaller array from a larger array in objective C?

I need to pick 32 distinctive objects from an NSMutableArray of 75 objects. it can be 1 to 32, 2 to 33 or 10 to 42. What functions should i use to get the new array? Sorry for being noob.
If you want N consecutive objects from a random index, try the following:
NSArray *arrayWithNConsecutiveObjects(NSArray *arr, int n)
{
int subIdx = arc4random_uniform((unsigned) (arr.count - n));
return [arr subarrayWithRange:NSMakeRange(subIdx, n)];
}
If you need 32 random objects, you can extend this method to randomly sort the array:
NSArray *arrayWithNObjects(NSArray *arr, int n)
{
arr = [arr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
// random sort
return arc4random_uniform(3) - 1; // one of -1, 0, and 1
}];
int subIdx = arc4random_uniform((unsigned) (arr.count - n));
return [arr subarrayWithRange:NSMakeRange(subIdx, n)];
}
You can use the appropriate method inherited from NSArray to retrieve a slice of 32 consecutive elements:
int offset = 4;
NSArray *slice = [array subarrayWithRange:NSMakeRange(offset, offset+32)];

Initializing NSArray of numbers

I have an non-mutable array that only needs to have numbers. How would I have to initialize this?
I have it like below right now but I'm thinking there has to be a better way. Can we do it like in C++? Something like this int list[5] = {1,2,3,4,5}; would that have any impact on the application?
myArray = [[NSArray alloc] initWithObjects: [NSNumber numberWithInt:1], [NSNumber numberWithInt:2], [NSNumber numberWithInt:3], nil];
Also, if I had a need for an array of arrays with only numbers, how would this look like? I'm new to obj-c and looking around online I've seen conflicting answers.
Not yet, but soon:
http://blog.ablepear.com/2012/02/something-wonderful-new-objective-c.html
Update: The new syntax is:
#[ #(20), #(10) ]
The #[] creates an array, the #(number) makes an NSNumber that can go in the array.
If it is non-mutable and only contains numbers just use the C array directly. There is nothing wrong with using C arrays in Objective-C, and in your case an NSArray is just unneeded overhead.
You could add a category to NSArray:
#implementation NSArray ( ArrayWithInts )
+(NSArray*)arrayWithInts:(const int[])ints count:(size_t)count
{
assert( count > 0 && count < 100 ) ; // just in case
NSNumber * numbers[ count ] ;
for( int index=0; index < count; ++index )
{
numbers[ index ] = [ NSNumber numberWithInt:ints[ index ]] ;
}
return [ NSArray arrayWithObjects:numbers count:count ] ;
}
#end
countof() looks like this:
#define countof(x) (sizeof(x)/sizeof(x[0]))
Use like this:
const int numbers[] = { 20, 10, 5, 2, 1, 0 } ;
NSArray * array = [ NSArray arrayWithInts:numbers count:countof(numbers) ] ) ;
Or you could just use #CRD's suggestion above...