Sortera värden med NSArrays?

Tråden skapades och har fått 6 svar. Det senaste inlägget skrevs .
1

Hej,

Jag är nybörjare med stort N när det gäller Cocoa. Har en fråga om arrays, och om någon kunde hjälpa mig vore det väldigt uppskattat

Jag vill sortera alfabetets bokstäver efter hur ofta de förekommer i en string. Har redan räknat ut frequencyn och gett varje värde en egen variabel. Nu skulle jag vilja ge varje bokstav i alfabetet dess respektive värde och sedan sortera efter värdet. Hur gör man?

En by the way-fråga också: om jag har ett antal textfields och vill att markeringen direkt ska flyttas till nästa så fort man gett ett av dem ett en-karaktär-långt värde, utan att behöva tabba - hur gör jag?

O

Ursprungligen av olindh:

Jag vill sortera alfabetets bokstäver efter hur ofta de förekommer i en string. Har redan räknat ut frequencyn och gett varje värde en egen variabel. Nu skulle jag vilja ge varje bokstav i alfabetet dess respektive värde och sedan sortera efter värdet. Hur gör man?

Eftersom du vill associera två värden med varandra låter det som du vill använda ett dictionary snarare än en array. Då kan du använda metoden -keysSortedByValueUsingSelector:, såhär:

NSEnumerator		*enumerator;
	NSMutableDictionary	*letters;
	NSArray				*keys;
	NSString			*letter;

	letters = [NSMutableDictionary dictionary];
	[letters setObject:[NSNumber numberWithInt:5] forKey:@a];
	[letters setObject:[NSNumber numberWithInt:15] forKey:@e];
	[letters setObject:[NSNumber numberWithInt:10] forKey:@i];
	
	keys = [letters keysSortedByValueUsingSelector:@selector(compare:)];
	enumerator = [keys reverseObjectEnumerator];
	
	while((letter = [enumerator nextObject]))
		NSLog(@"%@: %@", letter, [letters objectForKey:letter]);
Ursprungligen av olindh:

En by the way-fråga också: om jag har ett antal textfields och vill att markeringen direkt ska flyttas till nästa så fort man gett ett av dem ett en-karaktär-långt värde, utan att behöva tabba - hur gör jag?

NSTextField är en NSControl, så den skickar metoden -controlTextDidChange: till sin delegat varje gång användaren ändrar texten i fältet. Där kan du lägga in din kod för att hoppa vidare till nästa fält automatiskt. Du styr fokus med NSWindow-metoden -makeFirstResponder: och du kan fråga ditt NSTextField om vilket som är nästa fält med -nextKeyView:

[window makeFirstResponder:[textField nextKeyView]];

http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSControl_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/controlTextDidChange:

morris! Tipset om dictionaries hjälpte mig mycket. Tackar och bugar!

När det gäller delegater förstår jag inte. Är som jag sa nybörjare, och har aldrig jobbat med delegater innan. Du menade väl att jag skulle ändra koden i delegaten till fälten? Är det samma delegat för alla fält? Var kommer man åt delegatens kod?

O

Jag antar att du har någon sorts controllerobjekt för fönstret du har dina textfält i. Det objektet passar utmärkt att använda som delegat för fälten.

I Interface Builder, control-dra från varje textfält till ditt controllerobjekt och anslut dem till outleten "delegate". Det här gör att ditt objekt blir fältens delegat. I IB bör du också sätta upp din kedja av key views, så att den hoppar till rätt fält senare. Dra först en connection från fönstret till det första textfältet, anslut det till fönstrets outlet "initialFirstResponder". Det här är fältet som ska ha fokus när fönstret först öppnas. Dra sedan en connection från det fältet till nästa fält, anslut "nextKeyView". Gör samma sak med resten av textfälten. På det sista fältet, dra en connection till det första, anslut "nextKeyView".

I ditt controllerobjekt lägger du sedan till den här koden:

- (void)controlTextDidChange:(NSNotification *)notification {
	NSTextField		*textField;
	
	textField = [notification object];
	
	if([[textField stringValue] length] == 1)
		[[self window] makeFirstResponder:[textField nextKeyView]];
}

Det här implementerar metoden -controlTextDidChange:. När man skriver i textfälten kommer de kolla om de har en delegat och om delegaten svarar på den metoden, vilket du gör, alltså körs den. Vi får textfältet i NSNotifications -object och plockar ut det. Kollar sedan längden på strängen och om den är ett, ber fönstret flytta fokus till nästa textfält.

Tack morris! Det fungerar perfekt nu.

Kan jag fråga en till sak? Kan man på något sätt få ett textfält att förändras medan en action utförs? Jag menar, vanligtvis så ändras inte utseendet förrän actionen har kört färdigt, right? Men om man vill att ett textfält skall förändras, eller att något annat skall hända, medan actionen ännu inte är färdigkörd - hur gör man då? Är det ens möjligt?

O

När man förändrar attributen på en NSView kör den vanligen -setNeedsDisplay:YES vilket gör att de kommer ritas om i nästa iteration av runloopen. Du skulle kunna testa att skicka -display till textfältet, vilket ska rita om det omedelbart.

återigen fungerar ditt råd perfekt tackar!

1
Bevaka tråden