I have an array of an array of objects. The inner arrays have been sorted in order then added to an overall array. All the inner objects are the same thing with different values.
I am trying to go through those arrays and organize the objects in order from the average index value.
Example of the inner arrays sorted
obj 1 | obj 2 | obj 2
obj 2 | obj 1 | obj 1
obj 3 | obj 3 | obj 4
obj 4 | obj 4 | obj 3
then the output i would need from that after getting the average would be
obj 2
obj 1
obj 3
obj 4
I really only need the top three index averages but I would like to get all of them. So for example to get 3 I could do this
for (NSArray* innerArray in outterArray) {
for (NSString* str in innerArray) {
if ([innerArray indexOfObject:str] == 0) {
[first addObject:str];
}else if([innerArray indexOfObject:str] == 1){
[second addObject:str];
}else if ([innerArray indexOfObject:str] == 2){
[third addObject:str];
}
}
}
Then go through those three arrays and see what pops up where but there must be a better way of doing this and its probably something simple but I cant see it
All objects occur the same number of times, therefore you can compute the sum
of indices instead of the average for each object.
This can be done by enumerating once over all inner dictionaries, and updating
a hash map (dictionary) with the sum of indices for the current object.
(Note that indexOfObject:
is not needed here to locate the objects in the inner array.)
Then sort the objects according to the sum of the indices (which is the value
of the object in the dictionary):
NSArray *outerArray = #[
#[#"obj 1", #"obj 2", #"obj 3", #"obj 4"],
#[#"obj 2", #"obj 1", #"obj 3", #"obj 4"],
#[#"obj 2", #"obj 1", #"obj 4", #"obj 3"],
];
NSMutableDictionary *map = [NSMutableDictionary dictionary];
for (NSArray *innerArray in outerArray) {
NSUInteger index = 0; // Index of next object in the inner array
for (NSString *str in innerArray) {
// Add current index of this object to previous sum and update hash map
NSUInteger tmp = index + [map[str] unsignedIntegerValue];
map[str] = #(tmp);
index++;
}
}
NSArray *sorted = [[map allKeys] sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
return [map[obj1] compare:map[obj2]];
}];
NSLog(#"%#", sorted);
Output:
(
"obj 2",
"obj 1",
"obj 3",
"obj 4"
)
The dictionary map in this case is
{
"obj 1" = 2; // "obj 1" at indices 0 + 1 + 1
"obj 2" = 1; // "obj 2" at indices 1 + 0 + 0
"obj 3" = 7; // "obj 3" at indices 2 + 2 + 3
"obj 4" = 8; // "obj 4" at indices 3 + 3 + 2
}
Related
I am new in objective c. I have array please see sample. I need to
rearrange from 1,2,3 to 2,3,1. Thank you guys.
"M 90.5, 88", <- please pay attention to this
" C",
"84.083333373069763, 96.083333253860474", <- 1;
"87.5, 90.333333253860474", <- 2;
"84.5, 92.666666507720947", <- 3;
"M 171, 204", <- please pay attention to this
" C",
"161, 199.50000002980232", <- 1;
"168, 202.33333337306976", <- 2;
"165, 200.66666674613953", <- 3;
" C",
"153.16666674613953, 215.25", <- 1;
"148.5, 202.66666650772095", <- 2;
"150, 208.33333301544189", <- 3;
" C",
"136.5, 249", <- 1;
"146.83333349227905, 246.66666662693024", <- 2;
"141.66666698455811, 247.83333325386047" <- 3;
This is my code before and it works in a single Starting point(moveTO) only. what if I draw lots of lines it will create mutliple starting points
like
"M 82, 130.5 ",
" 76.333333253860474, 137.16666674613953 ",
" 78.833333253860474, 132.66666674613953 ",
" 75.666666507720947, 134.83333349227905 ",
" 86, 144.5 ",
" 77, 139.5 ",
" 81.5, 142",
"M 146, 137.5 ",
" 147.25, 152.66666674613953 ",
" 146.83333331346512, 142.5 ",
" 147.66666662693024, 147.5 ",
" 141.83333337306976, 166.08333349227905 ",
" 146.83333337306976, 157.83333349227905 ",
" 145.16666674613953, 163.16666698455811 ",
" 128.5, 170 ",
" 138.5, 169 ",
" 133.5, 169.5"
NSArray *myArray = #[#"M 198.16666666418314, 199.75",#"203.5, 198.5", and so on... ];
NSMutableArray *newArray = [NSMutableArray arrayWithArray:myArray];
for(int i=1;i<[newArray count];i=i+3) {
[newArray exchangeObjectAtIndex:i withObjectAtIndex:i+2];
[newArray exchangeObjectAtIndex:i withObjectAtIndex:i+1];
}
I figure it out. thanks guys.
for(int i=1;i<[newArray count];i++) {
NSString *strMovTo2 = [newArray objectAtIndex:i];
NSArray *elements2 = [strMovTo2 componentsSeparatedByString:#"-"];
newArray2 = [NSMutableArray arrayWithArray:elements2];
for(int j=1;j<[newArray2 count];j=j+3) {
[newArray2 exchangeObjectAtIndex:j withObjectAtIndex:j+2];
[newArray2 exchangeObjectAtIndex:j withObjectAtIndex:j+1];
}
newArray3 = [[NSMutableArray alloc] init];
for (int y = 2; y<[newArray2 count]; y=y+3){
[newArray3 addObject: [NSString stringWithFormat:#"%# %# %#", newArray2[y-1], newArray2[y], newArray2[y+1] ]];
}
curves = [newArray3 componentsJoinedByString:#" C "];
MovTOstart = [NSString stringWithFormat:#"-M %# C", newArray2[0]];
[svgFileToPast appendFormat:#"%# %#", MovTOstart, curves];
}
I need an array where I can store 3 values, and calculate the average of it.
After 3s the array is full, I would like to refresh every value starting from begin [0] of the array. So every 3s the the array is updated and I have the most recent average. For the moment when I add an object the array keeps growing.
This is the code I have at the moment:
//Inside function which loops every second so I can access myValue
self.myArray = [[NSMutableArray alloc] initWithCapacity:3];
[self.myArray addObject:[NSNumber numberWithDouble:myValue]];
for(int i = 0; i < self.myArray.count; i++) {
NSLog(#"Array %d: %#", i, self.myArray[i]);
}
Output
Array 0: 2
Array 1: 4
Array 2: 5
Array 3: 6
Array 4: 1
Just check if the size of your array is larger than 3. If so, remove the oldest element.
Here is a possible implementation:
Alloc and init the array:
self.myArray = [[NSMutableArray alloc] init];
Insert a new object and delete the oldest one:
[self.myArray insertObject:object atIndex:0];
if ( self.myArray.count > 3 )
{
[self.myArray removeLastObject];
}
It looks like you're trying to calculate a running average that gets updated every second. Here's a simple alternative approach that may work for you.
Initialize the average:
runningAverage = myValue;
Inside the loop:
const int WEIGHT = 3;
runningAverage = (runningAverage * (WEIGHT - 1) + myValue) / WEIGHT;
Here's what the output would look like:
Input: 1, 2, 3, 4, 101, 6, 7, 8
(Using an array)
Output: -, -, 2, 3, 36, 37, 38, 7
(Using running average)
Output: 1, 1.33, 1.88, 2.59, 35.4, 25.6, 19.4, 15.6
I'm currently making a quiz app. When a user starts the quiz random questions show up like you would expect from a quiz app. The problem is, it is not quite random. It does show random questions, but the questions repeat. I wanted to make sure they do not repeat until the end! My code is :
int Questions = arc4random_uniform(142);
switch (Questions) {
case 0:
break;
case 1:
break;
(...)
Isn't there a better way to do it? A way to just not repeat the questions? Thank you so much!
A shuffle may be your best solution:
// Setup
int questionCount = 10; // real number of questions
NSMutableArray *questionIndices = [NSMutableArray array];
for (int i = 0; i < questionCount; i++) {
[questionIndices addObject:#(i)];
}
// shuffle
for (int i = questionCount - 1; i > 0; --i) {
[questionIndices exchangeObjectAtIndex: i
withObjectAtIndex: arc4random_uniform((uint32_t)i + 1)];
}
// Simulate asking all questions
for (int i = 0; i < questionCount; i++) {
NSLog(#"questionIndex: %i", [questionIndices[i] intValue]);
}
NSLog output:
questionIndex: 6
questionIndex: 2
questionIndex: 4
questionIndex: 8
questionIndex: 3
questionIndex: 0
questionIndex: 1
questionIndex: 9
questionIndex: 7
questionIndex: 5
ADDENDUM
Example with actual text being printed after shuffling
// Setup
NSMutableArray *question = [NSMutableArray arrayWithObjects:
#"Q0 text", #"Q1 text", #"Q2 text", #"Q3 text", #"Q4 text",
#"Q5 text", #"Q6 text", #"Q7 text", #"Q8 text", #"Q9 text", nil];
// shuffle
for (int i = (int)[question count] - 1; i > 0; --i) {
[question exchangeObjectAtIndex: i
withObjectAtIndex: arc4random_uniform((uint32_t)i + 1)];
}
// Simulate asking all questions
for (int i = 0; i < [question count]; i++) {
printf("%s\n", [question[i] UTF8String]);
}
Sample output:
Q9 text
Q5 text
Q6 text
Q4 text
Q1 text
Q8 text
Q3 text
Q0 text
Q7 text
Q2 text
The idea is to use each question once until all questions have been used.
Sample code. Note that the questionIndex does not repeat.
// Setup
int questionCount = 10; // real number of questions
NSMutableArray *questionIndexes = [NSMutableArray array];
for (int i=0; i<questionCount; i++)
[questionIndexes addObject:#(i)];
// Simulate asking all questions
while (questionIndexes.count) {
// For each round
unsigned long arrayIndex = arc4random_uniform((uint32_t)questionIndexes.count);
int questionIndex = [questionIndexes[arrayIndex] intValue];
[questionIndexes removeObjectAtIndex:arrayIndex];
NSLog(#"arrayIndex: %lu, questionIndex: %i", arrayIndex, questionIndex);
}
NSLog output:
arrayIndex: 9, questionIndex: 9
arrayIndex: 5, questionIndex: 5
arrayIndex: 5, questionIndex: 6
arrayIndex: 3, questionIndex: 3
arrayIndex: 3, questionIndex: 4
arrayIndex: 4, questionIndex: 8
arrayIndex: 2, questionIndex: 2
arrayIndex: 0, questionIndex: 0
arrayIndex: 1, questionIndex: 7
arrayIndex: 0, questionIndex: 1
Any random generator is actually pseudorandom. By default it is started from the same initial value. To make it it "real random" you should supply unique start value i.e. "salt" for each run. As a simplest approach you can use [NSDate timeIntervalSinceReferenceDate].
Put your questions in an array and put the random number in the objectWithIndex method of NSMutableArray. Then remove the question from the array. Whenever a index is chosen, but there is not a question anymore, try it again.
I have opposite question for
If i have:
typedef enum {
SUNDAY = (1 << 0),
MONDAY = (1 << 1),
TUESDAY = (1 << 2),
WEDNESDAY = (1 << 3),
THURSDAY = (1 << 4),
FRIDAY = (1 << 5),
SATURDAY = (1 << 6),
} PFDateDays;
And my input is 65 for example (SUNDAY,SATURDAY) there is a clever way for etract this values from enum?
Here is my method:
-(NSMutableArray*)selectFromMyEnum {
NSMutableArray *returnArray = [[NSMutableArray alloc] init];
int myInput = 62;
NSArray *enumArray = #[#(SATURDAY),#(FRIDAY),#(THURSDAY),#(WEDNESDAY),#(TUESDAY),#(MONDAY),#(SUNDAY)];
for(NSNumber *numberInEnumArray in enumArray) {
if(myInput >= [numberInEnumArray integerValue]) {
[returnArray addObject:numberInEnumArray];
myInput -= [numberInEnumArray integerValue];
}
}
NSLog(#"%#",returnArray);
return returnArray;
}
And this is output:
(
64, //SATURDAY
1 //SUNDAY
)
So this is correct. But maybe there is method I don't know about that allow me to do this without this pointless assign enum to array etc..
Well the first thing that comes to my mind is this. Since your enum is nicely laid out for flagging you can do something like this:
Start with your highest enum value (SATURDAY) and use a bitwise and (&) to check if your value contains it. Then shift the comparison value right by 1 and repeat until your comparison value is zero.
PFDateDays comparison = SATURDAY;
//If your enum doesn't end at 1 like the above example,
//you could also use >= SUNDAY
while(((int)comparison) > 0) {
if((myVal & comparison) == comparison)
//Do what you want, this value is valid
comparison = comparison >> 1;
}
I have a table with 2 rows with each 3 columns in it and an Array with 5 values. These values should be displayed successively in the 3 columns, e.g.
indexPath.row 0: Array[0] | Array[1] | Array[2]
indexPath.row 1: Array[3] | Array[4] |
I want to create some coding, which puts my values (it doesn't care how much e.g. 5,6,7,...,20,21 in the format of 3 columns in rows) the rows are calculated at the size of the array with the values.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSMutableArray *values = [... getValues];
int no=0;
if (values) {
no=(values.count+1)/3;
}
else{
no=0;
}
return no;
}
My current problem is, I don't get the 5 values distributed in the columns.
I'm struggeling around with the calculation, these won't fit with the index of the array ...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//order values in 3 columns and 2 rows (currently)...
}
BR,
mybecks
Suppose COLS is the number of columss, and V is the number of values, where M is the matrix, and Vector is the values vector:
for i = 0 to V-1:
M[i div COLS][i mod COLS] = Vector[i]
Found a solution.
NSInteger count = numberOfValues;
NSInteger start = indexPath.row * 3;
NSInteger end = MIN(start + 3, count);
for(int i = start; i < end; i++)
{
if(i%3 == 0){//left}
if(i%3 == 1){//center}
if(i%3 == 2){//right}
}