comparing two data on aspx memo with the data it contains a ";" - c#

I enter the data in 2 aspx memo like this :
aspxmemo1 = php;visual basic;c#
aspxmemo2 = visual basic;javascript
question :
how to check if any data was similar between the 2 aspxmemo that it will show an error message.
Note:
In the above examples, the same data is: "Visual Basic".

Assuming your memo's are strings: if you split the strings on ';', you have nice collections, which are far more easy to operate on for example with Linq.
var aspxmemo1 = "php;visual basic;c#";
var aspxmemo2 = "visual basic;javascript";
var collection1 = aspxmemo1.Split(';');
var collection2 = aspxmemo2.Split(';');
if (collection1.Intersect(collection2).Any())
{
//Do Something
}
//Or iterate over the duplicate memo's (you get the point)
foreach(var item in collection1.Intersect(collection2))
{
Console.WriteLine(item + " occured in both collections!");
}

Try this way.
string aspxmemo1 = "php;visual basic;c#";
string aspxmemo2 = "visual basic;javascript";
string copies ="";
string[] group1 = aspxmemo1.Split(';');
string[] group2 = aspxmemo2.Split(';');
foreach (string x in group1)
{
if (group2.Contains<string>(x))
{
copies += x + Environment.NewLine;
}
}
MessageBox.Show(copies);

Related

C# how to write the whole array if a string within "array[1]" contains keyword

My current code is looping through a list containing saved strings in an array. Currently it looks for all strings in that array. I want to change this so that it only goes through (searching, looking) for strings within "log[1]"
Sorry, i dont know the word for "log[1]". Im new to programming. Keep reading and i think you will understand.
This is how i want to do it:
foreach (string[] item[1] in loggbok)
item[1] being log[1]. Number 1 is very important because I want to search only within log[1].
This is my current code for saving the whole array in my list:
List<string[]> loggbok = new List<string[]> { };
string[] log = new string[3]; //date, title, post
DateTime date = DateTime.Now;
log[0] = "\n\tDate: " + date.ToLongDateString() + " Kl: " + date.ToShortTimeString();
Console.WriteLine(log[0]);
Console.Write("\tTitle: ");
log[1] = "\tTitle: " + Console.ReadLine();
Console.Write("\tPost: ");
log[2] = "\tPost: " + Console.ReadLine();
loggbok.Add(log);
log = new string[3];
I save "log[1],log[2],log[3]"
The following code i want to make a search function which goes through my list and recognise all the strings within log[1] aka titles. If a string title is containing the users keyword all logs should join and the log will be printed.
As of now. I solved this by searching through all logs(1,2,3). This means that my program is searching currently for strings within (titles, date, posts). This makes it so that you can search for messages or "post" when i want the user to be restricted by only searching for titles.
So i thought maby if in my foreach loop i make "item" to "item[1]". Will that make my code to only look for "log[1]". I did not get that far though becouse writing "item[1]" is invalid syntax.
Current search function:
string key;
Console.Write("\n\tSearch: ");
key = Console.ReadLine();
//Searching through all log[] in loggbok.
//I want to change this line to item[1]
foreach (string[] item in loggbok)
{
//goes deeper and looks for all strings within log[].
foreach (string s in item)
{
//if a string is found containing key word, this block will run.
if (s.Contains(key))
{
foundItem = true;
Console.WriteLine(String.Join("\r\n", item));
index++;
}
}
}
Probably you can do it like this:
var result = loggbok.FirstOrDefault(x=> x.Any(s=> s.Contains(key));
Console.WriteLine(result?? "No record found");
You don't even need to loop, so what you need to do is retrieve the item from loggbok by the index.
// assign loggbokx of index 1, to variable item.
string[] item = loggbok[1];
// item will then have the 2nd (index=1) logbook.
// Note that index starts from 0.
// If you want to have the first one, then it should be loggbox[0]
// to make it even simpler you can write
// var item = loggbok[1];
// and the rest is the same...
//goes deeper and looks for all strings within log[].
foreach (string s in item)
{
//if a string is found containing key word, this block will run.
if (s.Contains(key))
{
foundItem = true;
Console.WriteLine(String.Join("\r\n", item));
index++;
}
}
Let's do it right!
Create a model class for your log:
class LogEntry
{
public DateTime Date { get; set; }
public string Title { get; set; }
public string Post { get; set; }
public override string ToString()
{
return "Date: " + Date.ToLongDateString() + " Kl: " + Date.ToShortTimeString()
+ "\tTitle: " + Title + "\tPost: " + Post;
}
}
Now we can comfortably use this model.
Let's populate the list with more records:
List<LogEntry> loggbok = new List<LogEntry>();
for (int i = 0; i < 5; i++)
{
LogEntry entry = new LogEntry();
entry.Date = DateTime.Now;
entry.Title = "title" + i;
entry.Post = "post" + i;
loggbok.Add(entry);
}
Let's print it:
foreach (var entry in loggbok)
Console.WriteLine(entry);
Due to the ToString method overload output looks out nice.
Let's find something:
string key = "title3";
var found = loggbok.Find(log => log.Title == key);
Console.WriteLine("Found:\n" + found);
We can use different methods of the List class, and LINQ extension methods.
If you need to save your data to a file and then read them from there, you can use json serialization.
For example, let's use the JavaScriptSerializer (don't forget to add a reference to the assembly):
JavaScriptSerializer jss = new JavaScriptSerializer();
// Save
File.WriteAllText("test.txt", jss.Serialize(loggbok));
// Load
loggbok = jss.Deserialize<List<LogEntry>>(File.ReadAllText("test.txt"));
This is the solution if anyone finds it intressting.
foreach (string[] item in loggbok)
{
foreach (string s in item)
{
//This was the magic line.
string searchTitle = item[1].ToLower();
if (searchTitle.Contains(titleKey.ToLower()))
{
Console.WriteLine("\n\tSearch hit #" + index);
foundItem = true;
Console.WriteLine(String.Join("\r\n", item));
index++;
break;
}
}
}

C# how write the whole array if string contains keyword

I am searching if a string within an stringarray contains a keyword.
If a string gets a match i want the array(s) which the string was found in to be output on the console.
Sofar i have managed to output every string that contains a keyword within the stringarray.
I have tried to work around this by outputting the array insteed but then i get this message "System.String[]"
However, that is not my intent. I wanted the array to be displayed. I wonder, how can i do this?
//Sorry for bad english.
Here are the relevant parts from my code:
List<string[]> loggbok = new List<string[]> { };
string[] log = new string[3]; //date, title, post
DateTime date = DateTime.Now;
log[0] = "\n\tDate: " + date.ToLongDateString() + " Time: " + date.ToShortTimeString();
Console.Write("\tTitle: ");
log[1] = "\tTitle: " + Console.ReadLine();
Console.Write("\tPost: ");
log[2] = "\tPost: " + Console.ReadLine();
loggbok.Add(log);
log = new string[3];
Console.Write("\n\tSearch: ");
string keyWord;
keyWord = Console.ReadLine();
foreach (string[] item in loggbok)
{
foreach (var s in item)
{
if (s.Contains(keyWord))
{
Console.WriteLine(item);
}
}
}`enter code here`
For displaying the whole array try this:
Console.WriteLine(String.Join("\r\n", item));
You can filter the array like this:
Console.WriteLine(String.Join("\r\n", item.Where(item => item.Contains(keyWord)).ToArray());
or
string[] filtered = item.Where(s => s.Contains(keyWord)).ToArray();
Console.WriteLine(String.Join("\r\n", filtered));
If you want to filter the whole loggbok (list of string arrays) use the SelectMany extension.
string[] filtered = loggbok.SelectMany(s => s.Contains(keyWord)).ToArray();
Console.WriteLine(String.Join("\r\n", filtered));
If I understand your question correctly, you want the whole array in which the keyword has been found.
What you do wrong is you state Console.WriteLine(item) which will only print that item.
Instead, make a function which returns true if the keyword has been found in this array and false if this has not happened. Your code would look something like this:
string keyWord;
keyWord = Console.ReadLine();
foreach (string[] item in loggbok)
{
if (checkItem(item)) {
for(int i = 0; i < item.Length; i++){
Console.WriteLine(item[i]);
}
}
}
public bool checkItem(string[] item, string keyWord) {
foreach(var s in item) {
if(s.Contains(keyWord))
return true;
}
return false;
}
This might help you.

C# compare fields from different lines in csv

I am trying to compare the value in the 0 index of an array on one line and the 0 index on the following line. Imagine a CSV where I have a unique identifier in the first column, a corresponding value in the second column.
USER1, 1P
USER1, 3G
USER2, 1P
USER3, 1V
I would like to check the value of [0] the next line (or previous if that's easier) to compare and if they are the same (as they are in the example) concatenate it to index 1. That is, the data should read as
USER1, 1P, 3G
USER2, 1P
USER3, 1V
before it gets passed onto the next function. So far I have
private void csvParse(string path)
{
using (TextFieldParser parser = new TextFieldParser(path))
{
parser.Delimiters = new string[] { "," };
while (!parser.EndOfData)
{
string[] parts = parser.ReadFields();
if (parts == null)
{
break;
}
contact.ContactId = parts[0];
long nextLine;
nextLine = parser.LineNumber+1;
//if line1 parts[0] == line2 parts[0] etc.
}
}
}
Does anyone have any suggestions? Thank you.
How about saving the array into a variable:
private void csvParse(string path)
{
using (TextFieldParser parser = new TextFieldParser(path))
{
parser.Delimiters = new string[] { "," };
string[] oldParts = new string[] { string.Empty };
while (!parser.EndOfData)
{
string[] parts = parser.ReadFields();
if (parts == null || parts.Length < 1)
{
break;
}
if (oldParts[0] == parts[0])
{
// concat logic goes here
}
else
{
contact.ContactId = parts[0];
}
long nextLine;
nextLine = parser.LineNumber+1;
oldParts = parts;
//if line1 parts[0] == line2 parts[0] etc.
}
}
}
If I understand you correctly, what you are asking is essentially "how do I group the values in the second column based on the values in the first column?".
A quick and quite succinct way of doing this would be to Group By using LINQ:
var linesGroupedByUser =
from line in File.ReadAllLines(path)
let elements = line.Split(',')
let user = new {Name = elements[0], Value = elements[1]}
group user by user.Name into users
select users;
foreach (var user in linesGroupedByUser)
{
string valuesAsString = String.Join(",", user.Select(x => x.Value));
Console.WriteLine(user.Key + ", " + valuesAsString);
}
I have left out the use of your TextFieldParser class, but you can easily use that instead. This approach does, however, require that you can afford to load all of the data into memory. You don't mention whether this is viable.
The easiest way to do something like this is to convert each line to an object. You can use CsvHelper, https://www.nuget.org/packages/CsvHelper/, to do the work for you or you can iterate each line and parse to an object. It is a great tool and it knows how to properly parse CSV files into a collection of objects. Then, whether you create the collection yourself or use CsvHelper, you can use Linq to GroupBy, https://msdn.microsoft.com/en-us/library/bb534304(v=vs.100).aspx, your "key" (in this case UserId) and Aggregate, https://msdn.microsoft.com/en-us/library/bb549218(v=vs.110).aspx, the other property into a string. Then, you can use the new, grouped by, collection for your end goal (write it to file or use it for whatever you need).
You're basically finding all the unique entries so put them into a dictionary with the contact id as the key. As follows:
private void csvParse(string path)
{
using (TextFieldParser parser = new TextFieldParser(path))
{
parser.Delimiters = new string[] { "," };
Dictionary<string, List<string>> uniqueContacts = new Dictionary<string, List<string>>();
while (!parser.EndOfData)
{
string[] parts = parser.ReadFields();
if (parts == null || parts.Count() != 2)
{
break;
}
//if contact id not present in dictionary add
if (!uniqueContacts.ContainsKey(parts[0]))
uniqueContacts.Add(parts[0],new List<string>());
//now there's definitely an existing contact in dic (the one
//we've just added or a previously added one) so add to the
//list of strings for that contact
uniqueContacts[parts[0]].Add(parts[1]);
}
//now do something with that dictionary of unique user names and
// lists of strings, for example dump them to console in the
//format you specify:
foreach (var contactId in uniqueContacts.Keys)
{
var sb = new StringBuilder();
sb.Append($"contactId, ");
foreach (var bit in uniqueContacts[contactId])
{
sb.Append(bit);
if (bit != uniqueContacts[contactId].Last())
sb.Append(", ");
}
Console.WriteLine(sb);
}
}
}

WebMatrix internal search engine

I've wrriten a code which searchs the database but i don't know why when i search for some specific keywords it'll show other links which are unrelated. here's the code and the result.
Page.Title = "Catalog Search";
var db = Database.Open("Shopping");
var searchWords = Request["searchTerm"].Split(' ');
IEnumerable<dynamic> result = Enumerable.Empty<string>();
var sqlSelect = "SELECT ProductId, ProductTitle FROM Products WHERE " +
"ProductTitle LIKE #0";
foreach(var word in searchWords)
{
result = result.Concat(db.Query(sqlSelect, "%" + word + "%").ToList());
}
so i searched for "Samsung LCD" and here's the result.
Samsung - 15" Series 9 Ultrabook Laptop
Samsung - Galaxy Tab 2 7.0
Samsung - 32" Class - LCD
Samsung - 32" Class - LCD
i've seen a php code which is exactly what i want but unfortunately i don't know how to convert it. here's the php code.
$searchTerms = explode(' ', $bucketsearch);
$searchTermBits = array();
foreach ($searchTerms as $term) {
$term = trim($term);
if (!empty($term)) {
$searchTermBits[] = "bucketname LIKE '%$term%'";
}
}
...
$result = mysql_query("SELECT * FROM buckets WHERE ".implode(' AND ', $searchTermBits).");
and the result of the php search code.
SELECT * FROM buckets WHERE bucketname LIKE '%apple%' AND bucketname LIKE '%and%' AND bucketname LIKE '%pear%'
I took the liberty of adding a few null checks and such, but the code for C# would pretty much look like this:
// make sure search terms are passed in, and remove blank entries
var searchTerms = Request["searchTerms"] == null ?
new string[] {} :
Request["searchTerms"].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
// build the list of query items using parameterization
var searchTermBits = new List<string>();
for (var i=0; i<searchTerms.Length; i++) {
searchTermBits.Add("bucketname LIKE #" + i);
}
// create your sql command using a join over the array
var query = "SELECT * FROM buckets";
if (searchTerms.Length > 0) {
query += " WHERE " + string.Join(" AND ", searchTermBits);
}
// ask the database using a lambda to add the %
var db = Database.Open("StarterSite");
var results = db.Query(query, searchTerms.Select(x => "%" + x + "%").ToArray());
// enjoy!
Response.Write(results.Count());
Let me know if you run into any more trouble!

How to remove duplicates from List<string> without LINQ? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Remove duplicates from a List<T> in C#
i have a List like below (so big email list):
source list :
item 0 : jumper#yahoo.com|32432
item 1 : goodzila#yahoo.com|32432|test23
item 2 : alibaba#yahoo.com|32432|test65
item 3 : blabla#yahoo.com|32432|test32
the important part of each item is email address and the other parts(separated with pipes are not important) but i want to keep them in final list.
as i said my list is to big and i think it's not recommended to use another list.
how can i remove duplicate emails (entire item) form that list without using LINQ ?
my codes are like below :
private void WorkOnFile(UploadedFile file, string filePath)
{
File.SetAttributes(filePath, FileAttributes.Archive);
FileSecurity fSecurity = File.GetAccessControl(filePath);
fSecurity.AddAccessRule(new FileSystemAccessRule(#"Everyone",
FileSystemRights.FullControl,
AccessControlType.Allow));
File.SetAccessControl(filePath, fSecurity);
string[] lines = File.ReadAllLines(filePath);
List<string> list_lines = new List<string>(lines);
var new_lines = list_lines.Select(line => string.Join("|", line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)));
List<string> new_list_lines = new List<string>(new_lines);
int Duplicate_Count = 0;
RemoveDuplicates(ref new_list_lines, ref Duplicate_Count);
File.WriteAllLines(filePath, new_list_lines.ToArray());
}
private void RemoveDuplicates(ref List<string> list_lines, ref int Duplicate_Count)
{
char[] splitter = { '|' };
list_lines.ForEach(delegate(string line)
{
// ??
});
}
EDIT :
some duplicate email addrresses in that list have different parts ->
what can i do about them :
mean
goodzila#yahoo.com|32432|test23
and
goodzila#yahoo.com|asdsa|324234
Thanks in advance.
say you have a list of possible duplicates:
List<string> emailList ....
Then the unique list is the set of that list:
HashSet<string> unique = new HashSet<string>( emailList )
private void RemoveDuplicates(ref List<string> list_lines, ref int Duplicate_Count)
{
Duplicate_Count = 0;
List<string> list_lines2 = new List<string>();
HashSet<string> hash = new HashSet<string>();
foreach (string line in list_lines)
{
string[] split = line.Split('|');
string firstPart = split.Length > 0 ? split[0] : string.Empty;
if (hash.Add(firstPart))
{
list_lines2.Add(line);
}
else
{
Duplicate_Count++;
}
}
list_lines = list_lines2;
}
The easiest thing to do is to iterate through the lines in the file and add them to a HashSet. HashSets won't insert the duplicate entries and it won't generate an exception either. At the end you'll have a unique list of items and no exceptions will be generated for any duplicates.
1 - Get rid of your pipe separated string (create an dto class corresponding to the data it's representing)
2 - which rule do you want to apply to select two object with the same id ?
Or maybe this code can be useful for you :)
It's using the same method as the one in #xanatos answer
string[] lines= File.ReadAllLines(filePath);
Dictionary<string, string> items;
foreach (var line in lines )
{
var key = line.Split('|').ElementAt(0);
if (!items.ContainsKey(key))
items.Add(key, line);
}
List<string> list_lines = items.Values.ToList();
First, I suggest to you load the file via stream.
Then, create a type that represent your rows and load them into a HashSet(for
performance considerations).
Look (Ive removed some of your code to make it simple):
public struct LineType
{
public string Email { get; set; }
public string Others { get; set; }
public override bool Equals(object obj)
{
return this.Email.Equals(((LineType)obj).Email);
}
}
private static void WorkOnFile(string filePath)
{
StreamReader stream = File.OpenText(filePath);
HashSet<LineType> hashSet = new HashSet<LineType>();
while (true)
{
string line = stream.ReadLine();
if (line == null)
break;
string new_line = string.Join("|", line.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries));
LineType lineType = new LineType()
{
Email = new_line.Split('|')[3],
Others = new_line
};
if (!hashSet.Contains(lineType))
hashSet.Add(lineType);
}
}

Categories

Resources