Reputation: 669
I have a list of file names (targetFileList), some of which are duplicates (ex. I have two files called m4.txt). The following statement finds the duplicated filenames and adds them to another list (currentTargetFiles):
currentTargetFiles = targetFileList.FindAll(item => item == baselineFilename);
As is, this line is returning a list of strings (filenames), which is good, but I also need their index value. Is there some way to modify it so that it also returns the indices of the files?
Upvotes: 2
Views: 3229
Reputation: 134035
You can select all the items, with their indexes, with:
tempList = targetFileList.Select((item, index) =>
new { Value = item, Index = index }).Where(x => x.Value == baselineFilename);
Now, you can create lists of the names and corresponding indexes with:
var indexes = tempList.Select(x => x.Index).ToList();
And the values:
currentTargetFiles = tempList.Select(x => x.Value).ToList();
Then, indexes[0]
will hold the list index of currentTargetFiles[0]
.
Upvotes: 2
Reputation:
Well, here is my answer to "find the duplicate names and their indices". It might not fit the presented problem exactly, as there is no baselineFilename
considered - but that is covered by other answers. YMMV.
var names = new [] {"a", "a", "c", "b", "a", "b"};
var duplicatesWithIndices = names
// Associate each name/value with an index
.Select((Name, Index) => new { Name, Index })
// Group according to name
.GroupBy(x => x.Name)
// Only care about Name -> {Index1, Index2, ..}
.Select(xg => new {
Name = xg.Key,
Indices = xg.Select(x => x.Index)
})
// And groups with more than one index represent a duplicate key
.Where(x => x.Indices.Count() > 1);
// Now, duplicatesWithIndices is typed like:
// IEnumerable<{Name:string,Indices:IEnumerable<int>}>
// Let's say we print out the duplicates (the ToArray is for .NET 3.5):
foreach (var g in duplicatesWithIndices) {
Console.WriteLine("Have duplicate " + g.Name + " with indices " +
string.Join(",", g.Indices.ToArray()));
}
// The output for the above input is:
// > Have duplicate a with indices 0,1,4
// > Have duplicate b with indices 3,5
Of course, the provided results must be used correctly - and this depends on what must ultimately be done.
Upvotes: 7
Reputation: 15104
Is linq a requirement?
A traditional for loop and a dictionary would do fine:
Dictionary<int, string> currentTargetFiles = new Dictionary<int, string>();
for (int i = 0; i < targetFileList.Count; ++i)
if(targetFileList[i] == baselineFilename)
currentTargetFiles.Add(i, targetFileList[i]);
P.S.:
Just realized that you comparing an exact string (item == baselineFilename
).
If this is the case you don't even need to keep each value for each index (since all values are the same).
List<int> currentTargetFilesIndices = new List<int>();
for (int i = 0; i < targetFileList.Count; ++i)
if(targetFileList[i] == baselineFilename)
currentTargetFiles.Add(i);
Upvotes: 1
Reputation: 44048
int i = -1;
var currentTargetFiles = targetFileList.Select(x => new
{
Value = x,
Index = i++
})
.Where(x => x.Value == baselineFilename);
Upvotes: 2