How to get nsstring matching count with other nsstring object? - cocoa

I searching a way to get match count of nsstring objects for a long time.
but I can't find.
How to get match count of String_one and String_Two?
I need your help..
NSString *String_one = #"A!B!C!D!E!F!G";
NSString *String_Two = #"BEF";
// matching progress
// :
// :
// and then result display
NSLog(#"matching count : %d",[??????]);
// result what i want.
// matching count : 3 (A!B!C!D!E!F!G vs BEF => 3 character matches)

If you want to find longest common subsequence here you have link:
http://en.wikipedia.org/wiki/Longest_common_subsequence_problem
But if you want count only how many how many character from first string appear in second string you can write algorithm by yourself. Example:
for ( each character in StringFirst ) {
if( character appear in StringSecond )
++count;
}

Related

LINQ: select rows where any word of string start with a certain character

I want extract from a table all rows where in a column (string) there is at least one word that starts with a specified character.
Example:
Row 1: 'this is the first row'
Row 2: 'this is th second row'
Row 3: 'this is the third row'
If the specified character is T -> I would extract all 3 rows
If the specified character is S -> I would extract only the second column
...
Please help me
Assuming you mean "space delimited sequence of characters, or begin to space or space to end" by "word", then you can split on the delimiter and test them for matches:
var src = new[] {
"this is the first row",
"this is th second row",
"this is the third row"
};
var findChar = 'S';
var lowerFindChar = findChar.ToLower();
var matches = src.Where(s => s.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Any(w => w.ToLower()[0] == lowerFindChar));
The LINQ Enumerable.Any method tests a sequence to see if any element matches, so you can split each string into a sequence of words and see if any word begins with the desired letter, compensating for case.
Try this:
rows.Where(r => Regex.IsMatch(r, " [Tt]"))
You can replace the Tt with Ss (both assuming you want either upper case or lower case).
The problem of course is, what is a "word"?
Is the character sequence 'word' in the sentence above a word according to your definition? It doesn't start with a space, not even a white-space.
A definition of a word could be:
Define wordCharacter: something like A-Z, a-z.
Define word:
- the non-empty sequence of wordCharacters at the beginning of a string followed by a non-wordcharacter
- or the non-empty sequence of wordCharacters at the end of a string preceded by a non-wordcharacter
- any non-empty sequence of wordCharacters in the string preceded and followed by a non-wordcharacter
Define start of word: the first character of a word.
String: "Some strange characters: 'A', 9, äll, B9 C$ X?
- Words: Some, strange characters, A
- Not Words: 9, äll, B9, C$ X?
So you first have to specify precisely what you mean by word, then you can define functions.
I'll write it as an extension method of IEnumerable<string>. Usage will look similar to LINQ. See Extension Methods Demystified
bool IsWordCharacter(char c) {... TODO: implement your definition of word character}
static IEnumerable<string> SplitIntoWords(this string text)
{
// TODO: exception if text null
if (text.Length == 0) return
int startIndex = 0;
while (startIndex != text.Length)
{ // not at end of string. Find the beginning of the next word:
while (startIndex < text.Length && !IsWordCharacter(text[startIndex]))
{
++startIndex;
}
// now startIndex points to the first character of the next word
// or to the end of the text
if (startIndex != text.Length)
{ // found the beginning of a word.
// the first character after the word is either the first non-word character,
// or the end of the string
int indexAfterWord = startWordIndex + 1;
while (indexAfterWord < text.Length && IsWordCharacter(text[indexAfterWord]))
{
++indexAfterWord;
}
// all characters from startIndex to indexAfterWord-1 are word characters
// so all characters between startIndexWord and indexAfterWord-1 are a word
int wordLength = indexAfterWord - startIndexWord;
yield return text.SubString(startIndexWord, wordLength);
}
}
}
Now that you've got a procedure to split any string into your definition of words, your query will be simple:
IEnumerabl<string> texts = ...
char specifiedChar = 'T';
// keep only those texts that have at least one word that starts with specifiedChar:
var textsWithWordThatStartsWithSpecifiedChar = texts
// split the text into words
// keep only the words that start with specifiedChar
// if there is such a word: keep the text
.Where(text => text.SplitIntoWords()
.Where(word => word.Length > 0 && word[0] == specifiedChar)
.Any());
var yourChar = "s";
var texts = new List<string> {
"this is the first row",
"this is th second row",
"this is the third row"
};
var result = texts.Where(p => p.StartsWith(yourChar) || p.Contains(" " + yourChar));
EDITED:
Alternative way (I'm not sure it works in linq query)
var result = texts.Where(p => (" " + p).Contains(" " + yourChar));
you can use .ToLower() if you want Case-insensitive check.

LINQ| How to transform only the first letter to lowercase

Using LINQ how can I transform only the first letter of s.Password to lowercase
if (s.Password == password){}
i want that the first char of s.Password will be in lower case,
i tried :
if( s.Password[0].toString().toLower() + s.Password(1) ) == password ){}
If you would like to make a decision based on an item's position in LINQ, you can use Select that takes a Func with two parameters - the item and its index:
var pwd = "BadPassword";
var res = new string(
pwd.Select((c, i) => i==0 ? char.ToLower(c) : c).ToArray()
); // produces badPassword
The functor above converts the initial character at i==0 to lower case, while leaving all other characters in place.
Demo 1.
Note: LINQ is not necessary for this conversion. You can do the same thing in one line by using Substring:
var res = char.ToLower(pwd[0]) + pwd.Substring(1);
Demo 2.

How to find the uncommon words from two files using only terminal commands in OSX?

I have two files of four letter words.
File A contains all possible combinations of four letter words.
The words in this file, are one word per line, and are sorted like:
aaaa
aaab
aaac
.
.
aaba
aabb
File B contains "bad words". These are also in sorted order. The words in File B are a subset of File A. Each file has only unique words. There are no duplicates in a given file.
What is an efficient way to find only the "good words" in file A and save it in a second file from the terminal ?
I can easily write an Objective-C program using the following code:
//Omitted file handling code. Passing in both the files words as arrays.
-(NSMutableArray)goodWords:(NSMutableArray*)allWords badWords:(NSMutableArray*)badWords
{
int ap = 0; int bp=0;
NSMutableIndexSet *indices = [[NSMutableIndexSet alloc]init];
while(bp<badWords.count)
{
NSString* bs = [badWords objectAtIndex:bp];
NSString* as = [allWords objectAtIndex:ap];
if([as isEqualToString:bs])
{
//Make note of index containing bad word.
[indices addIndex:ap];
bp++; ap++; //Move both pointers ahead.
}
else
{
ap++; // Since both arrays are sorted, and the words don't match, I move the ap ahead. (since it is pointing at a "good word".
}
}
//Make a copy of the original array of "good words".
NSMutableArray *result = [NSMutableArray arrayWithArray:allWords];
[result removeObjectsAtIndexes:indices]; //Remove the bad words.
[indices release];
return result;
}
Since these are lists of words, I can't use GREP. Is there a way to do this using only terminal commands in OSX ? I don't know where to begin with unix / terminal commands.
EDIT: Fixed a mistake in code;
EDIT: Added comments explaining algorithm.
EDIT: Made NSIndexSet NSMutableIndexSet;
EDIT: Accidentally typed AP instead of AllWords
EDIT: Fixed leak.
This should get you close:
$ cat goodwords
aaaa
aaab
aaac
aaad
aaae
$ cat badwords
aaaa
aaad
$ comm -3 goodwords badwords | grep -v '^\t$'
aaab
aaac
aaae
(the grep is there as comm uses tabs to separate "columns").
As an added bonus, your Objective-C version should store the values in an NSSet (as there are no dupes) and then use:
NSMutableSet *goodWords = [allWords mutableCopy];
[goodWords minusSet:badWords];

Cocoa: Extracting "A" from "Æ"

I have a bunch of NSStrings from which I would like to grab the first character of and match them up in the range A-Z and # as a catch all for things that don't apply.
Different graphemes (I believe that's the correct word after some wiki'ing) have been giving me trouble. For example, I would like to extract A from "Æ".
I have taken a look at CFStringTransform, normalize and fold but none of had the desired effect.
Is there a reliable way of doing this? All the strings I'm working with are UTF8 if that makes a difference.
Æ cannot be broken down into components. It is not a compound glyph of A+E, but is a separate glyph. Compound glyphs are things like a+`
The thing about "Æ" is that it is an ascii character in itself. Not a combination of two different characters so you can't extract the A from it because it is only 1 Character.
Edit:
Although you could perform a check to see if the String equals "Æ" and if it does tell it to switch it with "A" or convert it to its dec, form and subtract 81 which would give you an "A".
Did you want to get rid of all æ?
This should work if you do.
NSString *string = #"Æaæbcdef";
string = [string stringByReplacingOccurrencesOfString:#"æ" withString:#"a"];
string = [string stringByReplacingOccurrencesOfString:#"Æ" withString:#"A"];
Edit
Rereading, you only seem to want the first character:
NSString *string = #"Æaæbcdef";
NSString *firstChar = [string substringToIndex:1];
firstChar = [firstChar stringByReplacingOccurrencesOfString:#"æ" withString:#"a"];
firstChar = [firstChar stringByReplacingOccurrencesOfString:#"Æ" withString:#"A"];
NSString *finalString = [NSString stringWithFormat:#"%#%#", firstChar, [string substringFromIndex:1]];

Split NSString preserving quoted substrings

I need to split up a string which is separated by commas while preserving any quoted substrings (which may have commas too).
String example:
NSString *str = #"One,Two,\"This is part three, I think\",Four";
for (id item in [str componentsSeparatedByString:#","])
NSLog(#"%#", item);
This returns:
One
Two
"This is part three
I think"
Four
The correct result (respecting quoted substrings) should be:
One
Two
"This is part three, I think"
Four
Is there a reasonable way to do this, without re-inventing or re-writing quote-aware parsing routines?
Let's think about this a different way. What you have is a comma-seperated string, and you want the fields in the string.
There's some code for that:
https://github.com/davedelong/CHCSVParser
And you'd do this:
NSString *str = #"One,Two,\"This is part three, I think\",Four";
NSArray *lines = [str CSVComponents];
for (NSArray *line in lines) {
for (NSString *field in line) {
NSLog(#"field: %#", field);
}
}
Here is a C# answer to the same problem.
C# Regex Split - commas outside quotes
You could probably use the same Regex in Objective-C
NSString split Regex with ,(?=(?:[^']*'[^']*')*[^']*$)

Resources