Trimming a string in a list - c#

I have a list that contains string values. I need to trim the leading and ending values. Here is the code:
using EnterpriseDT.Net.Ftp;
public List<FTPFile> FileList = new List<FTPFile>();
FTP = new FTPConnection() { ServerAddress = _host, UserName = _user, Password = _password };
FTP.Connect();
FTP.TransferType = FTPTransferType.BINARY;
FTP.ChangeWorkingDirectory(_as400_directory);
FTP.LocalDirectory = _local_directory;
FileList.AddRange(FTP.GetFileInfos());
FTP.Close();
The FileList list contains following example values:
test 123 11/01/12 *STMF File1.csv somegarbagevalues
test 123 11/01/12 *STMF File2.csv somegarbagevalues
test 123 11/01/12 *STMF File3.csv somegarbagevalues
What I need to do is capture online the file name (ex. File1.csv, File2.csv ...) Is there a way to trim the unwanted values without looping through the list or trim when I do the FileList.AddRange statement?

LINQ makes this easy:
FileList.AddRange(FTP.GetFileInfos().Select(x => x.Trim()));
where Trim() would be a method (possibly an extension method) on FTPFile which returned an FTPFile with trimmed filename.

FTPFile is a class and has a property "Name". You were probably looking at the ToString() implementation of the FTPFile class that gave you all the properties at once.
See:
http://www.enterprisedt.com/products/edtftpnet/doc/api/EnterpriseDT.Net.Ftp.FTPFileMembers.html
Just use:
foreach(FTPFile f in FileList)
{
string name = f.Name;
// Do whatever you want with name.
}

Related

How to Remove Directories From EnumerateFiles?

So I'm working on a program that will list all the files in a directory. Pretty simple. Basically, when I do this: List<string> dirs = new List<string>(Directory.EnumerateFiles(target));, I don't want it to include the directory and all. Just the file name. When I run my code;
List<string> dirs = new List<string>(Directory.EnumerateFiles(target));
Console.WriteLine($"Folders and files in this directory:\n");
foreach (string i in dirs) {
Console.WriteLine($"> {i}");
}
it gives me the following:
C:\Users\Camden\Desktop\Programming\Visual Studio\C#\DirectoryManager\DirectoryManager\bin\Debug\DirectoryManager.exe
I just want the DirectoryManager.exe part, so I looked it up and I found that you can replace strings inside of strings. Like so: i.Replace(target, "");. However, this isn't doing anything, and it's just running like normal. Why isn't it replacing, and how should I instead do this?
Use methods from the System.IO.Path class.
var fullfile = #"C:\Users\Camden\Desktop\Programming\Visual Studio\C#\DirectoryManager\DirectoryManager\bin\Debug\DirectoryManager.exe";
var fileName = Path.GetFileName(fullfile); // DirectoryManager.exe
var name = Path.GetFileNameWithoutExtension(fullfile); // DirectoryManager
The simplest way is to use the Select IEnumerable extension
(you need to have a using Linq; at the top of your source code file)
List<string> files = new List<string>(Directory.EnumerateFiles(target)
.Select(x => Path.GetFileName(x)));
In this way the sequence of files retrieved by Directory.EnumerateFiles is passed, one by one, to the Select method where each fullfile name (x) is passed to Path.GetFileName to produce a new sequence of just filenames.
This sequence is then returned as a parameter to the List constructor.
And about your question on the Replace method. Remember that the Replace method doesn't change the string that you use to call the method, but returns a new string with the replacement executed. In NET strings are immutable.
So if you want to look at the replacement you need
string justFileName = i.Replace(target, "");
An alternative to using Directory.EnumerateFiles, would be DirectoryInfo.EnumerateFiles. This method returns an IEnumerable<FileInfo>. You can then make use of the FileInfo.Name property of each of the returned objects. Your code would then become:
var files = new DirectoryInfo(target).EnumerateFiles();
Console.WriteLine("Files in this directory:\n");
foreach (FileInfo i in files) {
Console.WriteLine($"> {i.Name}");
}
For just the list of file names:
List<string> fileNames = new DirectoryInfo(target).EnumerateFiles().Select(f => f.Name).ToList();
Alternatively, if you want both files and directories, you can use EnumerateFileSystemInfos. If you need to know if you have a file vs a directory you can query the Attributes property and compare it to the FileAttributes flags enumeration.
var dirsAndFiles = new DirectoryInfo(target).EnumerateFileSystemInfos();
Console.WriteLine("Folders and files in this directory:\n");
foreach (var i in dirsAndFiles) {
var type = (i.Attributes & FileAttributes.Directory) == FileAttributes.Directory ? "Directory" : "File";
Console.WriteLine($"{type} > {i.Name}");
}
The FileSystemInfo.Name property will return either the file's name (in case of a file) or the last directory in the hierarchy (for a directory)--so just the subdirectory name and not the full path ("sub" instead of "c:\sub").

Iterating whole list and updating string using ToLower - Not working

Technologies using.
C#
.NET 4.0
Visual Studio 2010
Problem.
I have a List<User> which contains an Email property. I want to lowercase all the email addresses within the list, but my implementation is not working. I'm using the following statement:
emails.ToList().ForEach(e => e.ToLower());
This didnt work at all for email addresses like Catherine.Burke#email.co.uk. I built the following to test this:
string email = "Catherine.Burke#email.co.uk";
email = email.ToLower();
Console.WriteLine("Email: " + email);
string email2 = "Catherine.Burke#email.co.uk";
string email3 = "Gareth.bradley#email.co.uk";
List<string> emails = new List<string>();
emails.Add(email2);
emails.Add(email3);
emails.ToList().ForEach(e => e.ToLower());
emails.ToList().ForEach(delegate(string e)
{
Console.WriteLine("ForEach deletegate : " + e);
});
List<EmailAddress> emailAddresses = new List<EmailAddress>();
emailAddresses.Add(new EmailAddress { FullAddress = "Catherine.Burke#email.co.uk" });
emailAddresses.Add(new EmailAddress { FullAddress = "Gareth.bradley#email.co.uk" });
emailAddresses.ToList().ForEach(e => e.FullAddress.ToLower());
emailAddresses.ToList().ForEach(delegate(EmailAddress e)
{
Console.WriteLine("EmailAddress delegate: " + e.FullAddress);
});
foreach (EmailAddress em in emailAddresses)
{
Console.WriteLine("Foreach Print: " + em.FullAddress);
}
Now I thought it might be the Culture and as these are names, it kept them uppercase, but when I used ToLower() on a singular string it worked. The above ran with the following output, as you can see the 1st line shows an email address with lowercase characters, whereas the implementation of the various List's I tried using ForEach() have not worked. I'm presuming my implementation of ForEach() is incorrect?
Making my comment an answer as requested:
Use a simple for-loop. List.ForEach is a method where you get the string as argument, you can't replace the whole reference there and since strings are immutable you can't change them either. You have to reassign the string returned from String.ToLower to your variable:
for(int i = 0; i < emails.Count; i++)
emails[i] = emails[i].ToLower();
Side-note: if you are making all emails lowercase to get a case-insensitive comparison it's better to use the String.Equals overload with the right StringComparison
string email1 = "Catherine.Burke#email.co.uk";
string email2 = "catherine.burke#email.co.uk";
if (String.Equals(email1, email2, StringComparison.InvariantCultureIgnoreCase))
{
// ...
}
emails.ToList().ForEach(e => e.ToLower()); does just call ToLower() but does not assign the result.
What you want is:
var lowerEmails = emails.Select(e => e.ToLower()).ToList();
Try this:
emailAddresses.ToList().ForEach(e => e.FullAddress = e.FullAdress.ToLower());
As weertzui altready mentions the ForEach-method simply calls the delegate. However the result of this action is not used in your code in any way.
However I´d strongly recommend to use a simply foreach:
foreach(var mail in emailadresses) mail.FullAdress = mail.FullAdress.ToLower();
which seems better readable to me.

How to remove a specific string from list<strings>

I've got a list of strings called xyz the string has this structure iii//abcd, iii//efg. how can I loop through this list and remove only iii// ?
I have tried this but it remove everything. thanks
string mystring = "iii//";
xyz.RemoveAll(x=> x.Split ('//')[0].ToString().Equals (mystring));
Removing all the strings who start with iii//:
xyz.RemoveAll(x => x.StartsWith(#"iii//"));
Removing the iii// from all strings:
var newList = xyz.Select(x => x.Replace(#"iii//", string.Empty)).ToList();
You can try this also which will remove the string from list if it starts with "iii/" other wise not.
string mystring = "iii//";
xyz.RemoveAll(x=>x.StartsWith(mystring));
I believe OP wants something to remove iii// from all strings:
string prefix = "iii///";
List<string> xyz = ...;
var result = xyz.Select(x => x.Substring(prefix.Length)).ToList();
Note: this of course assumes that each string really starts with prefix.

Using GetFiles but splitting the results to show full path and just the filename

I am using “GetFiles” to extract files in a specified folder as shown below:
Directory.GetFiles(_dirPath, File_Filter);
This creates a string array which is fine but now I need to do something similar but create a Tuple array where each Tuple holds the full path including filename and also just the filename. So at the moment I have this in my string
C:\temp\test.txt
The new code needs to create a Tuple where each one looks similar to this:
Item1 = C:\temp\test.txt
Item2 = test.txt
I’m guessing I could do this this with a bit of Linq but am not sure. Speed and efficiency is too much of a problem as the lists will be very small.
You should use Directory.EnumerateFiles with LINQ which can improve performance if you don't need to consume all files. Then use the Path class:
Tuple<string, string>[] result = Directory.EnumerateFiles(_dirPath, File_Filter)
.Select(fn => Tuple.Create( fn, Path.GetFileName(fn) ))
.ToArray();
Use DirectoryInfo.GetFiles to return FileInfo instances, which have both file name and full name:
var directory = new DirectoryInfo(_dirPath);
var files = directory.GetFiles(File_Filter);
foreach(var file in files)
{
// use file.FullName
// use file.Name
}
That's much more readable than having tuple.Item1 and tuple.Item2. Or at least use some anonymous type instead of tuple, if you don't need to pass this data between methods:
var files = from f in Directory.EnumerateFiles(_dirPath, File_Filter)
select new {
Name = Path.GetFileName(f),
FullName = f
};
string[] arrayOfFiles = Directory.GetFiles(PathName.Text); // PathName contains the Path to your folder containing files//
string fullFilePath = "";
string fileName = "";
foreach (var file in arrayOfFiles)
{
fullFilePath = file;
fileName = System.IO.Path.GetFileName(file);
}

C# Retrieve Values from URL and insert records

In my code I have received, by way of a url, a comma delimited list of id's e.g.
12,13,14,15,16 etc..
I have got these into a string (Tools) which I have Split.
I now need to loop through each value and use it in an insert statement but I have got stuck can anyone help.
The C# below is based on an SDK so it is uses some functions that you may not have seen.
string userc = GetContextInfo("User", "UserId");
string tools = Dispatch.EitherField("selectedTools");
tools.Split(',');
string pID = Dispatch.EitherField("key16");
Record recRelTool = new Record("RelatedTools");
recRelTool.SetField("rato_CreatedBy", userc);
recRelTool.SetField("rato_Status", "active");
recRelTool.SetField("rato_server", pID);
recRelTool.SetField("rato_tool", tools);
recRelTool.SaveChanges();
Dispatch.Redirect(Url("1453"));
Where the ("rato_tools", tools) needs to be one of the tool id's in the value I have. I need to loop through until all of the tool id's have been used.
The call to split does not split your string, it returns an array of strings. You need to enumerate through this array to use one tool id at a time. Try the following:
string userc = GetContextInfo("User", "UserId");
string tools = Dispatch.EitherField("selectedTools");
string[] toolIds = tools.Split(',');
foreach (string toolId in toolIds)
{
Record recRelTool = new Record("RelatedTools");
recRelTool.SetField("rato_CreatedBy", userc);
recRelTool.SetField("rato_Status", "active");
recRelTool.SetField("rato_server", pID);
recRelTool.SetField("rato_tool", toolId);
recRelTool.SaveChanges();
}
Dispatch.Redirect(Url("1453"));
you have to assign your split return value:
var splitted = tools.Split(',');
http://msdn.microsoft.com/en-us/library/tabh47cf.aspx
and then you can iterate the collection:
foreach(string item in splitted)
{
//do something
}

Categories