<commit_before>//
//  NSString+RemoveEmoji.swift
//  NSString+RemoveEmoji
//
//  Created by woxtu on 2017/01/07.
//  Copyright (c) 2017 woxtu. All rights reserved.
//

import Foundation

fileprivate let CombiningEnclosingKeycap: UInt32 = 0x20E3
fileprivate let VaridationSelector15: UInt32 = 0xFE0E
fileprivate let VaridationSelector16: UInt32 = 0xFE0F

public extension NSString {
    public func containsEmoji() -> Bool {
        let codepoints = (self as String).unicodeScalars.map { $0.value }
        
        if let first = codepoints.first, let last = codepoints.last {
            let isKeycapEmoji = last == CombiningEnclosingKeycap && codepoints.contains(VaridationSelector16)
            let isEmoji = CodePointSet.contains(first) && last != VaridationSelector15
            
            return isKeycapEmoji || isEmoji
        } else {
            return false
        }
    }
    
    @objc(stringByRemovingEmoji)
    public func removingEmoji() -> NSString {
        let buffer = NSMutableString(capacity: self.length)
        self.enumerateSubstrings(in: NSMakeRange(0, self.length), options: .byComposedCharacterSequences) { substring, _, _, _ in
            if let substring = substring, !substring.containsEmoji() {
                buffer.append(substring)
            }
        }
        return buffer
    }<commit_msg>Exposed containsEmoji() to Objective C<commit_after>//
//  NSString+RemoveEmoji.swift
//  NSString+RemoveEmoji
//
//  Created by woxtu on 2017/01/07.
//  Copyright (c) 2017 woxtu. All rights reserved.
//

import Foundation

private extension UInt32 {
    static let combiningEnclosingKeycap: UInt32 = 0x20E3
    static let varidationSelector15: UInt32 = 0xFE0E
    static let varidationSelector16: UInt32 = 0xFE0F
}

public extension NSString {
    @objc
    public func containsEmoji() -> Bool {
        let codepoints = (self as String).unicodeScalars.map { $0.value }
        
        if let first = codepoints.first, let last = codepoints.last {
            let isKeycapEmoji = last == .combiningEnclosingKeycap && codepoints.contains(.varidationSelector16)
            let isEmoji = CodePointSet.contains(first) && last != .varidationSelector15
            
            return isKeycapEmoji || isEmoji
        } else {
            return false
        }
    }
    
    @objc(stringByRemovingEmoji)
    public func removingEmoji() -> NSString {
        let buffer = NSMutableString(capacity: self.length)
        self.enumerateSubstrings(in: NSMakeRange(0, self.length), options: .byComposedCharacterSequences) { substring, _, _, _ in
            if let substring = substring, !substring.containsEmoji() {
                buffer.append(substring)
            }
        }
        return buffer
    }
{'fraction_non_alphanumeric': 0.08832116788321168, 'fraction_numerical': 0.027007299270072994, 'mean_word_length': 2.5322164948453607, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4872022', 'n_tokens_mistral': 859, 'n_tokens_neox': 819, 'n_words': 192}