То, что вы хотите, невозможно без пользовательского UDF. В Scala вы можете сделать что-то вроде этого:
val data = sc.parallelize(Seq(
"""{"userId": 1, "someString": "example1",
"varA": [0, 2, 5], "varB": [1, 2, 9]}""",
"""{"userId": 2, "someString": "example2",
"varA": [1, 20, 5], "varB": [9, null, 6]}"""
))
val df = sqlContext.read.json(data)
df.printSchema
// root
// |-- someString: string (nullable = true)
// |-- userId: long (nullable = true)
// |-- varA: array (nullable = true)
// | |-- element: long (containsNull = true)
// |-- varB: array (nullable = true)
// | |-- element: long (containsNull = true)
Теперь мы можем определить zip
udf:
import org.apache.spark.sql.functions.{udf, explode}
val zip = udf((xs: Seq[Long], ys: Seq[Long]) => xs.zip(ys))
df.withColumn("vars", explode(zip($"varA", $"varB"))).select(
$"userId", $"someString",
$"vars._1".alias("varA"), $"vars._2".alias("varB")).show
// +------+----------+----+----+
// |userId|someString|varA|varB|
// +------+----------+----+----+
// | 1| example1| 0| 1|
// | 1| example1| 2| 2|
// | 1| example1| 5| 9|
// | 2| example2| 1| 9|
// | 2| example2| 20|null|
// | 2| example2| 5| 6|
// +------+----------+----+----+
С сырым SQL:
sqlContext.udf.register("zip", (xs: Seq[Long], ys: Seq[Long]) => xs.zip(ys))
df.registerTempTable("df")
sqlContext.sql(
"""SELECT userId, someString, explode(zip(varA, varB)) AS vars FROM df""")
К сожалению, нет очень, можно сделать здесь. В основном необходимо принять решение: повторно спроектируйте свое приложение так, чтобы оно могло обработать объект асинхронным способом или использовать неутвержденную, архитектуру устаревшую представления приложения модальные предупреждения.
, не зная информации о Вашем фактическом дизайне и как Вы обрабатываете эти объекты, трудно дать дальнейшую информацию. Первое, что пришло на ум, тем не менее, несколько мыслей могли бы быть:
Это может быть действительно сверхсложно для того, в чем Вы нуждаетесь, как бы то ни было. В этом случае моя рекомендация состояла бы в том, чтобы просто пойти с использованием устаревшим, но это действительно зависит от Ваших требований пользователя.
В отличие от Windows I не полагают, что существует способ заблокироваться на модальных диалоговых окнах. Вход (например, пользователь, нажимающий кнопку), будет обработан на Вашем основном потоке, таким образом, не будет никакого способа заблокироваться.
Для Вашей задачи необходимо будет или передать сообщение стек и затем продолжить, где Вы кончили.
Когда один объект перестал работать, прекратите обрабатывать объекты в дереве, обратите внимание, какой объект перестал работать (предполагающий, что существует порядок, и можно взять, где Вы кончили), и подбросьте лист. Когда пользователь отклоняет лист, имейте didEndSelector:
, метод начинает обрабатывать снова от объекта, с которым он кончил, или не делайте, в зависимости от returnCode
.
На всякий случай, если кто-то ищет это (я сделал), я решил это со следующим:
@interface AlertSync: NSObject {
NSInteger returnCode;
}
- (id) initWithAlert: (NSAlert*) alert asSheetForWindow: (NSWindow*) window;
- (NSInteger) run;
@end
@implementation AlertSync
- (id) initWithAlert: (NSAlert*) alert asSheetForWindow: (NSWindow*) window {
self = [super init];
[alert beginSheetModalForWindow: window
modalDelegate: self didEndSelector: @selector(alertDidEnd:returnCode:) contextInfo: NULL];
return self;
}
- (NSInteger) run {
[[NSApplication sharedApplication] run];
return returnCode;
}
- (void) alertDidEnd: (NSAlert*) alert returnCode: (NSInteger) aReturnCode {
returnCode = aReturnCode;
[[NSApplication sharedApplication] stopModal];
}
@end
Затем запущено синхронно NSALERT так просто, как:
AlertSync* sync = [[AlertSync alloc] initWithAlert: alert asSheetForWindow: window];
int returnCode = [sync run];
[sync release];
Примечание. Для повторных вхоронцев, как обсуждалось, поэтому будьте осторожны, если это делать.
Решение заключается в вызове
[NSApp runModalForWindow:alert];
после beginSheetModalForWindow. Также необходимо реализовать делегат, который перехватывает действие "диалог закрылся" и вызывает [NSApp stopModal] в ответ.
вот мой ответ:
Создайте глобальную переменную класса NSInteger alertReturnStatus
- (void)alertDidEndSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
{
[[sheet window] orderOut:self];
// make the returnCode publicly available after closing the sheet
alertReturnStatus = returnCode;
}
- (BOOL)testSomething
{
if(2 != 3) {
// Init the return value
alertReturnStatus = -1;
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
[alert addButtonWithTitle:@"OK"];
[alert addButtonWithTitle:@"Cancel"];
[alert setMessageText:NSLocalizedString(@"Warning", @"warning")];
[alert setInformativeText:@"Press OK for OK"];
[alert setAlertStyle:NSWarningAlertStyle];
[alert setShowsHelp:NO];
[alert setShowsSuppressionButton:NO];
[alert beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:@selector(alertDidEndSheet:returnCode:contextInfo:) contextInfo:nil];
// wait for the sheet
NSModalSession session = [NSApp beginModalSessionForWindow:[alert window]];
for (;;) {
// alertReturnStatus will be set in alertDidEndSheet:returnCode:contextInfo:
if(alertReturnStatus != -1)
break;
// Execute code on DefaultRunLoop
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]];
// Break the run loop if sheet was closed
if ([NSApp runModalSession:session] != NSRunContinuesResponse
|| ![[alert window] isVisible])
break;
// Execute code on DefaultRunLoop
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]];
}
[NSApp endModalSession:session];
[NSApp endSheet:[alert window]];
// Check the returnCode by using the global variable alertReturnStatus
if(alertReturnStatus == NSAlertFirstButtonReturn) {
return YES;
}
return NO;
}
return YES;
}
Надеюсь, это поможет, Ваше здоровье - Ханс