IQueryable<string> ScannedBarcodes = XYZDb.tblScannedBarcodes
.Where(i => i.PullNo == lblPullNo.Text)
.Select(i => i.Barcode);
The result view shows something like
"678765,090909,243454,675434"
Now I want to add all the comma-separated values into a list.
Rest of my code is below:
foreach (var item in ScannedBarcodes)
{
List<string> _barcodes = new List<string>();
_barcodes.Add(item);
}
How to split it?
Thanks in advance
The splitting can be done using Linq as follows.
var _barcodes =
ScannedBarcodes.SelectMany(iString => iString.Split(new char[]{ ','}))
.ToList();
Use
_barcodes.AddRange(item.Split(','));
There's no a single string with commas - that's just the debugger display. The IQueryable is a enumerable list of values already.....
IQueryable<string> ScannedBarcodes = XYZDb.tblScannedBarcodes
.Where(i => i.PullNo == lblPullNo.Text)
.Select(i => i.Barcode);
List<string> _barcodes = new List<string>();
_barcodes.AddRange(ScannedBarcodes);
There's really no need to loop over those values - just create your List<string> and then add the whole IQueryable collection to it in a single call to .AddRange() ...
Related
So I have a Query that searches for various items. But I just want their Id so I used a projection to return me only the Ids and not the other elements of the item. but converting from ObjectId .ToString() and then .ToList() returns me a List<char> instead List<string>
var items = await this.ItemAppService.GetAllAsync(expression,
x => new
{
Ids = x.Id.ToString().ToList(),
});
var Ids = items.SelectMany(x => x.Ids.Select(x => x)).ToList();
I would like to understand why i'm returning a List<Char> and how I convert it to List<String>
The first ToList is unnecessary, you want strings, and with that ToList() invocation you are converting your strings to char arrays. So the code should be rewritten as:
var items = await this.ItemAppService.GetAllAsync(expression,
x => new
{
Id = x.Id.ToString(),
});
var ids = items.Select(x => x.Id).ToList();
.ToString().ToList() returns a New List<char>
Yes, because a string is an IEnumerable<char> (a bunch of characters that can be enumerated over). ToList is an extension method on all IEnumerable<T>, that returns a List<T>.
So the Ids property in the anonymous object is already a List<char>:
x => new
{
// this "Ids" is already a List<char>
Ids = x.Id.ToString().ToList(),
});
You then do some more shuffling on it, but not meaningfully changing anything. x.Ids.Select(x => x) returns an Innumerable<char> with the same contents as x.Ids. And SelectMany adds up all those IEnumerable<char> in each of the anonymous objects into one big IEnumerable<char>, which you then convert to a list.
I'm not sure why you have used an anonymous object here. If you just want a List<string> with all the IDs, just do:
var ids = await this.ItemAppService.GetAllAsync(
expression,
// assuming x.Id is not already a string
x => x.Id.ToString()
).ToList();
Check the code bellow. Here i am creating a method that simply should remove the duplicate from the list foo. If you see the list values they are product id and quantity derived by : so the first part of number before : is product and and second part of number after : is the product quantity. I am taking this list into RemoveDuplicateItems() method for processing. This method should remove all matching product id items from whole list but my current method just returns exactly same list which i am taking on input. How can i fix my method to remove those item from list which has matching first part number. (first part number means before :)
The final output on doo variable it should remove the first from from list which is 22:15 since it has matching with second one.
C#:
[HttpPost]
public JsonResult DoSomething()
{
var foo = new List<string>();
foo.Add("22:10");//this should removed by RemoveDuplicateItems() since it has `22` matching with second one
foo.Add("22:15");
foo.Add("25:30");
foo.Add("26:30");
var doo = RemoveDuplicateItems(foo);
return Json("done");
}
public List<string> RemoveDuplicateItems(List<string> AllItems)
{
var FinalList = new List<string>();
var onlyProductIds = new List<string>();
foreach (var item in AllItems)
{
Match result = Regex.Match(item, #"^.*?(?=:)");
onlyProductIds.Add(result.Value);
}
var unique_onlyProductIds = onlyProductIds.Distinct().ToList();
foreach (var item in AllItems)
{
Match result = Regex.Match(item, #"^.*?(?=:)");
var id = unique_onlyProductIds.Where(x => x.Contains(result.Value)).FirstOrDefault();
if (id != null)
{
FinalList.Add(item);
}
}
return FinalList;
}
Does this work for you?
List<string> doo =
foo
.Select(x => x.Split(':'))
.GroupBy(x => x[0], x => x[1])
.Select(x => $"{x.Key}:{x.Last()}")
.ToList();
There are multiple ways to achieve this, one is, as suggested by #Aluan Haddad is to use Linq. His comment uses the query syntax but would could use the method syntax too (I assumed you use C#8):
List<string> doo = foo.GroupBy(str => str[0..2])
.Select(entry => entry.Last())
.ToList();
Note that this works because the current implementation of GroupBy preserves ordering.
you can do it using Linq :
var doo = foo.Select(x =>
{
var split = x.Split(':');
return new { Key = split[0], Value = split[1] };
})
.GroupBy(x => x.Key)
.OrderBy(x => x.Key)
.Select(x =>
{
var max = x.LastOrDefault();
return $"{max.Key}:{max.Value}";
}
).ToList();
Existing legacy code is as follows:
List<object> myItems;
//myItems gets populated by a method call
foreach (object[] item in myItems)
{
string Id = item[0].ToString();
string Number = item[1].ToString();
//now do some processing if Number satisfies some criteria
}
would like to convert this using linq to select all Ids that match a certain Number.
All suggestions would be appreciated.
Thanks.
Use Select() and Where()
bool IsSatisfyingNumber(String number) {
// True if number satisfies some criteria
}
List<String> matchingIds = myItems
.Where(item => IsSatisfyingNumber(item[1].ToString()))
.Select(item => item[0].ToString())
.ToList();
The list myItems contains items of type object where each this item is actually object[] so we need to cast to object[] first and then filter and select based on the searched certain number.
string certainNumber = "1";
var myIds = myItems
.Where(o => ((object[]) o)[1].ToString() == certainNumber)
.Select(o => ((object[]) o)[0].ToString());
The equality operator on strings performs an ordinal (case-sensitive and culture-insensitive) comparison so change it in the Where... if you need some different kind of comparison in your case.
Got it working and wanted to share the information:
var myIds =
(from item in myItems.Cast<object[]>()
select new
{ Id = item[0], Number = (string)item[1] }
)
.Where(x => x.Number == filtercondition)
.Select(x => (string)x.Id)
.ToList();
How can I turn the following statement back to List<DocumentData>
IEnumerable<IGrouping<string, DocumentData>> documents =
documentCollection.Select(d => d).GroupBy(g => g.FileName);
the goal is to get List that should be smaller than documentCollection.
FileName contains duplicates so I want to make sure I don't have duplicate names.
I have also tried the following but it's still providing me with duplicate file names
documentCollection =
documentCollection.GroupBy(g => g.FileName).SelectMany(d => d).ToList();
Each IGrouping<string, DocumentData> is an IEnumerable<DocumentData>, so you could simply call SelectMany to flatten the sequences:
var list = documents.SelectMany(d => d).ToList();
Edit: Per the updated question, it seems like the OP wants to select just the first document for any given filename. This can be achieved by calling First() on each IGrouping<string, DocumentData> instance:
IEnumerable<DocumentData> documents =
documentCollection.GroupBy(g => g.FileName, StringComparer.OrdinalIgnoreCase)
.Select(g => g.First())
.ToList();
You haven't said what T should stand for in List<T> you're looking for, so here are couple the most likely to be desired:
List<DocumentData> - rather pointless as you already have that on documentCollection
var results = documents.SelectMany(g => g).ToList();
List<KeyValuePair<string, List<DocumentData>>
var results =
documents.Select(g => new KeyValuePair(g.Key, g.ToList())).ToList();
List<string> - just the names
var results = documents.Select(g => g.Key).ToList();
List<IGrouping<string, DocumentData>>
var results = documents.ToList();
How can I convert my list of strings:
List<string> appliedFilters = filterString.Split(',').Select(n => n).ToList();
Into a list without duplicates?
My list of strings (appliedFilters) looks like this:
7-27,
2-37,
7-28,
9-18,
9-22,
9-80
I need to output this list without duplicates in the first part of the string, e.g:
7-27-28, 2-37, 9-18-22-80
I'm sure there's a LINQ query here somewhere, but cannot figure it out.
filterString.Split(',')
.Select(s => s.Split('-'))
.GroupBy(ss => ss[0])
.Select(group => string.Join("-", new[]{group.Key}.Concat(group.Select(ss => ss[1])).ToArray()));