LoginSignup
7
7

More than 5 years have passed since last update.

絵文字カウント

Last updated at Posted at 2015-06-22

Swiftの文字カウントがよくないので対策方法のメモ

追記あり 2015/12/20

何がよくないかっていうと国旗の絵文字が複数並んでたら、1文字とカウントしてしまうとこ。

var str = "abc"
println("\(str): \(count(str))") 
// abc: 3     …問題ない

str = "🇯🇵"
println("\(str): \(count(str))") 
// 🇯🇵: 1     …問題ない

str = "🇯🇵🇧🇷🇨🇭"
println("\(str): \(count(str))") 
// 🇯🇵🇧🇷🇨🇭: 1   …どうかしてる

とりあえず、こんな感じで対策してみた

extension String
{
    func unicodeCount() -> UInt
    {
        var cnt2:UInt = 0
        for c in self.unicodeScalars {
            switch c.value {
            // Combining Diacritical Marks for Symbols
            case 0x20D0...0x20FF:
                break
            // Variation Selectors
            case 0xFE00...0xFE0F:
                break
            // Regional Indicator symbols
            case 0x1F1E6...0x1F1FF:
                cnt2++
            default:
                cnt2 += 2
            }
        }
        return cnt2/2
    }
}
var str = "abc"
println("\(str): \(str.unicodeCount())") 
// abc: 3     …問題ない

str = "🇯🇵"
println("\(str): \(str.unicodeCount())") 
// 🇯🇵: 1     …問題ない

str = "🇯🇵🇧🇷🇨🇭"
println("\(str): \(str.unicodeCount())") 
// 🇯🇵🇧🇷🇨🇭: 3   …問題ない

いいんじゃないの。文字化けするから書いてないけど囲み文字もOK。

Objective-Cだったらこれでいいんだけどね
http://qiita.com/matsuokah/items/a435e3c86318a793d307

環境

  • OS X 10.10.3
  • Xcode 6.3

追記 2015/12/20

Swift 2.1 になったことだし、新しい絵文字も増えたので。

まず、普通のカウント

var str = "abc"
print("\(str): \(str.characters.count)")
// abc: 3     …問題ない

str = "🇯🇵"
print("\(str): \(str.characters.count)")
// 🇯🇵: 1     …問題ない

str = "🇯🇵🇧🇷🇨🇭"
print("\(str): \(str.characters.count)")
// 🇯🇵🇧🇷🇨🇭: 1    …やっぱりどうかしてる

str = "🤕🤒"
print("\(str): \(str.characters.count)")
// 🤕🤒: 2    …問題ない

str = "🖖🏾🤘🏿🖐🏻"
print("\(str): \(str.characters.count)")
// 🖖🏾🤘🏿🖐🏻: 6    …どうかしてる

最後のは 6文字であってるんじゃないかって思うかもしれないけど、
スクリーンショット 2015-12-20 17.33.09.png
Xcode 7.2 で見たらやっぱりどうかしてる(iOS 9.1 でも同じ)

新しい絵文字も入ったので対策の方も修正。

extension String
{
    func unicodeCount() -> UInt
    {
        var cnt2:UInt = 0
        for c in self.unicodeScalars {
            switch c.value {
            // Combining Diacritical Marks for Symbols
            case 0x20D0...0x20FF:
                break
            // Variation Selectors
            case 0xFE00...0xFE0F:
                break
            // Regional Indicator symbols
            case 0x1F1E6...0x1F1FF:
                cnt2 += 1
            // Fitzpatrick skin type
            case 0x1F3FB...0x1F3FF:
                break
            default:
                cnt2 += 2
            }
        }
        return cnt2/2
    }
}

やってみた。

var str = "abc"
print("\(str): \(str.unicodeCount())")
// abc: 3     …問題ない

str = "🇯🇵"
print("\(str): \(str.unicodeCount())")
// 🇯🇵: 1     …問題ない

str = "🇯🇵🇧🇷🇨🇭"
print("\(str): \(str.unicodeCount())")
// 🇯🇵🇧🇷🇨🇭: 3    …問題ない

str = "🤕🤒"
print("\(str): \(str.unicodeCount())")
// 🤕🤒: 2    …問題ない

str = "🖖🏾🤘🏿🖐🏻"
print("\(str): \(str.unicodeCount())")
// 🖖🏾🤘🏿🖐🏻: 3   …問題ない

スクリーンショット 2015-12-20 17.46.28.png

うん。ええんちゃう。

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7