快速通过Unicode将国家代码转换为表情符号标志
我正在寻找一种快速的方法来使类似:
let germany = "DE"
进入
let flag = "\u{1f1e9}\u{1f1ea}"
即D到1f1e9和E到1f1ea的映射是什么我正在寻找.utf8作为字符串,但这返回一个整数。
FWIW我的总体目标是能够采用任意国家/地区代码并获得相应的表情符号标志。
编辑:我也很好,只要持有一个做此映射的表(如果有的话)。 我在附近搜索,但没有找到。
5个解决方案
72 votes
这是将两个字母的国家/地区代码转换为其表情符号标志的通用公式:
func flag(country:String) -> String {
let base = 127397
var usv = String.UnicodeScalarView()
for i in country.utf16 {
usv.append(UnicodeScalar(base + Int(i)))
}
return String(usv)
}
let s = flag("DE")
编辑糟糕,无需传递嵌套的String.UnicodeScalarView结构。 事实证明,String正是出于此目的使用了append方法。 所以:
func flag(country:String) -> String {
let base : UInt32 = 127397
var s = ""
for v in country.unicodeScalars {
s.append(UnicodeScalar(base + v.value))
}
return s
}
再次编辑,在Swift 3中,他们取消了将UnicodeScalar附加到字符串的功能,并且使UnicodeScalar初始化程序失败(Xcode 8种子6),所以现在看起来像这样:
func flag(country:String) -> String {
let base : UInt32 = 127397
var s = ""
for v in country.unicodeScalars {
s.unicodeScalars.append(UnicodeScalar(base + v.value)!)
}
return String(s)
}
matt answered 2020-07-22T14:45:22Z
17 votes
如果有人在Objective C中寻找解决方案,这是方便的类别:
@interface NSLocale (RREmoji)
+ (NSString *)emojiFlagForISOCountryCode:(NSString *)countryCode;
@end
@implementation NSLocale (RREmoji)
+ (NSString *)emojiFlagForISOCountryCode:(NSString *)countryCode {
NSAssert(countryCode.length == 2, @"Expecting ISO country code");
int base = 127462 -65;
wchar_t bytes[2] = {
base +[countryCode characterAtIndex:0],
base +[countryCode characterAtIndex:1]
};
return [[NSString alloc] initWithBytes:bytes
length:countryCode.length *sizeof(wchar_t)
encoding:NSUTF32LittleEndianStringEncoding];
}
@end
测试:
for ( NSString *countryCode in [NSLocale ISOCountryCodes] ) {
NSLog(@"%@ - %@", [NSLocale emojiFlagForISOCountryCode:countryCode], countryCode);
}
输出:🇦🇩-公元🇦🇪-AE🇦🇫-自动对焦🇦🇬-AG🇦🇮-AI...
RolandasR answered 2020-07-22T14:45:52Z
6 votes
马特答案的两种优化。
无需在Swift 4中传递嵌套的String
为了避免传递小写字符串,我添加了uppercased()
这是代码。
func flag(from country:String) -> String {
let base : UInt32 = 127397
var s = ""
for v in country.uppercased().unicodeScalars {
s.unicodeScalars.append(UnicodeScalar(base + v.value)!)
}
return s
}
Lumialxk answered 2020-07-22T14:46:25Z
2 votes
深入了解哑光答案
Swift 2版本
public static func flag(countryCode: String) -> Character {
let base = UnicodeScalar("🇦").value - UnicodeScalar("A").value
let string = countryCode.uppercaseString.unicodeScalars.reduce("") {
var string = $0
string.append(UnicodeScalar(base + $1.value))
return string
}
return Character(string)
}
Swift 3版本,摘自[https://github.com/onmyway133/Smile/blob/master/Sources/Smile.swift#L52]
public func emoji(countryCode: String) -> Character {
let base = UnicodeScalar("🇦").value - UnicodeScalar("A").value
var string = ""
countryCode.uppercased().unicodeScalars.forEach {
if let scala = UnicodeScalar(base + $0.value) {
string.append(String(describing: scala))
}
}
return Character(string)
}
onmyway133 answered 2020-07-22T14:46:53Z
0 votes
对于更实用的方法,不使用可变变量,请使用以下命令:
private func flag(country: String) -> String {
let base: UInt32 = 127397
return country.unicodeScalars
.flatMap({ UnicodeScalar(base + $0.value) })
|> String.UnicodeScalarView.init
|> String.init
}
|>运算符是函数应用程序运算符,它像“管道”一样工作,以获取更自然的读取顺序:我们获取标量,将它们映射为新的标量,将其转换为视图,并将其转换为字符串。
它的定义如下:
infix operator |> : MultiplicationPrecedence
func |> (left: T, right: (T) -> U) -> U {
return right(left)
}
没有自定义运算符,我们仍然可以没有可变状态,就像这样:
private func flag(country: String) -> String {
let base: UInt32 = 127397
return String(String.UnicodeScalarView(
country.unicodeScalars.flatMap({ UnicodeScalar(base + $0.value) })
))
}
但是恕我直言,这读起来有些“向后”,因为自然的操作流程既不读入也不读入,而是读了一点。
Svein Halvor Halvorsen answered 2020-07-22T14:47:31Z