I have two different Classes:
class X
{
public int TX1 { get; set; }
public string TX2 { get; set; }
public string OX1 { get; set; }
}
class Y
{
public int TY1 { get; set; }
public string TY2 { get; set; }
public string TY3 { get; set; }
public string OY1 { get; set; }
}
eg:
OX1 => 1,2,3,4
OY1 => 2,1
Now i need to check atleast one value match is found.
Suggest me some solution using LINQ.
var listOY1 = OY1.Split(',');
bool b = OX1.Split(',').Any(x=>listOY1.Contains(x));
Related
I am creating bundles in my app and a bundle is defined as follows
Having a BundleId != null
Having a CountWithinBundle
A bundle is "full" when it has 3 members
I am trying to write a query to find "non full" bundles, below is where I am at but it gives me the second within a bundle every time since I am using the < 3
How can I modify this so that it gives me the last"non full" bundle Item, i,e an ItemInBasket where there are less than 3 entries with the same bundleId and Department so I can add a new item into the same bundle
var itemInBasket = basketToUpdate.ItemsInBasket.OrderByDescending(c => c.ThisItemsCountWithinBundle)
.Where(s => !string.IsNullOrEmpty(s.BundleId))
.Where(i => i.ThisItemsCountWithinBundle < 3)
.Where(s => s.Item.Department == itemToAdd.Item.Department)
.FirstOrDefault();
the class model looks like this
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace slapi.Models
{
class BasketModel
{
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
public string UserId { get; set; }
public string Brand { get; set; }
public int BasketLevel { get; set; }
//Start New Basket props
public int MaxBasketLevel { get; set; } = 6;
public Nullable<decimal> BasketLevelProgress { get; set; }
public decimal BasketLevelDiscount { get; set; }
public decimal WhitePriceStoreSummary { get; set; }
public Nullable<decimal> RedPriceStoreSummary { get; set; }
public Nullable<decimal> CheckoutDiscount { get; set; }
public Nullable<decimal> CheckoutDiscountPercent { get; set; }
public string Currency { get; set; } = "SEK";
public List<XForYStatusInformation> XForYInformations { get; set; }
//End New Basket props
public string ConsumerName { get; set; }
public string StoreId { get; set; }
public bool IsRedeemed { get; set; } = false;
public bool IsDeleted { get; set; } = false;
public List<ItemInBasket> ItemsInBasket { get; set; }
public string CreatedDate { get; set; }
public string CreatedDateUtc { get; set; }
public string CreatedBy { get; set; }
public string UpdatedDate { get; set; }
public string UpdatedDateUtc { get; set; }
public string UpdatedBy { get; set; }
public Nullable<int> CountHistory { get; set; } = 0;
}
class ItemInBasket
{
public StorelensItemModel_V2 Item { get; set; }
public Nullable<int> ItemRowPosition { get; set; }
public bool UsedForWeightCalculation { get; set; }
public bool IsPaused { get; set; }
public string BundleId { get; set; }
public int ThisItemsCountWithinBundle { get; set; } = 0;
public int BundleNeededQty { get; set; } = 3;
}
class XForYStatusInformation
{
public string Sticker { get; set; }
public string Text { get; set; }
public string BundleId { get; set; }
public string Department { get; set; }
}
}
The problem is that you're querying individual items, so you lose their mutual relationships (i.e. belonging to the same basket). The basketToUpdate has all required information, basically something like this:
basketToUpdate
.Select(b => new
{
Bundles = b.ItemsInBasket
.GroupBy(i => i.BundleId)
.Select(g => new
{
BundleId = g.Key,
ItemCount = g.Count(),
LastItem = g.OrderByDescending(c => c.ThisItemsCountWithinBundle)
.FirstOrDefault()
})
})
.Where(x => x.Bundles.Any(b => ItemCount < 3))
This gives you baskets with non-full bundles in which you can filter the bundles with ItemCount < 3.
I don't know the function of this s.Item.Department == itemToAdd.Item.Department predicate, so I didn't try to fit it in.
I want to check if some items are same in a list based on a item present in the list.
List<ProductDetailDTO> productDTOs;
The ProductDetailDTO is -
public class ProductDetailDTO
{
public int ProductId { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public byte[] Image { get; set; }
public string Description { get; set; }
public string Brand { get; set; }
public string GUID { get; set; }
public string VariantName { get; set; }
public string VariantValue { get; set; }
public decimal Price { get; set; }
}
Now, I want to display all VariantName and VariantValue with the same GUIDs together.
How can I achieve this?
try with this
productDTOs.GroupBy(x => x.GUID,(key,item) => new
{
VariantName= item.Select(y=>y.VariantName),
VariantValue = item.Select(y => y.VariantValue),
}).ToList()
I am getting product data from our ERP through SQL queries whereby the returned data is very flat- at the Size level. A product has 3 levels:
Style
Colours
Sizes
A style has many colours and a colour has many sizes.
I have created the following models:
public class Ap21Style
{
public int StyleIdx;
public string StyleCode;
public IList<Ap21Clr> Clrs { get; set; } = new List<Ap21Clr>();
}
public class Ap21Clr
{
public int ClrIdx { get; set; }
public string ColourCode { get; set; }
public string ColourName { get; set; }
public string ColourTypeCode { get; set; }
public string ColourTypeName { get; set; }
public IList<Ap21Sku> Skus { get; set; } = new List<Ap21Sku>();
}
public class Ap21Sku
{
public int SkuIdx { get; set; }
public string SizeCode { get; set; }
public int SizeSequence { get; set; }
public string Barcode { get; set; }
}
My ProductResult looks like this:
public int StyleIdx { get; set; }
public int ClrIdx { get; set; }
public int SkuIdx { get; set; }
public string StyleCode { get; set; }
public string ColourCode { get; set; }
public string ColourName { get; set; }
public string SizeCode { get; set; }
public int SizeSequence { get; set; }
public string ColourTypeCode { get; set; }
public string ColourTypeName { get; set; }
public string Barcode { get; set; }
public string WebData { get; set; }
What would be an effective way to loop over the results and create the Ap21Style models whereby they are a composite object with Ap21Clr's, then at the row level, the Colours have Ap21Sku's?
Assuming something like this
List<ProductResult> products = GetPropducts();
Composing the styles would involve grouping the data by the composite keys
List<Ap21Style> results = products
.GroupBy(p => new { p.StyleIdx, p.StyleCode })
.Select(g => new Ap21Style {
StyleIdx = g.Key.StyleIdx,
StyleCode = g.Key.StyleCode,
Clrs = g.GroupBy(s => new {
s.ClrIdx,
s.ColourCode,
s.ColourName,
s.ColourTypeCode,
s.ColourTypeName
}).Select(g1 => new Ap21Clr {
ClrIdx = g1.Key.ClrIdx,
ColourCode = g1.Key.ColourCode,
ColourName = g1.Key.ColourName,
ColourTypeCode = g1.Key.ColourTypeCode,
ColourTypeName = g1.Key.ColourTypeName,
Skus = g1.Select(s => new Ap21Sku {
Barcode = s.Barcode,
SizeCode = s.SizeCode,
SizeSequence = s.SizeSequence,
SkuIdx = s.SkuIdx
}).ToList()
}).ToList()
}).ToList();
I have a list like this ( already open with the visual studio debugger ) :
As you can see the list is made up of other objects of the same type list , my need is to run through all the children , regardless by the Index and verify that the FID of that object is the same as the one passed by the UI . Once you found matching server that returns the same object .
i can try this for test,
but considering I only top-level items , those with index 0 , does not flow in all:
AttachmentFolders childWithId17 = ApplicationContext.Instance.companyList[0].AttachmentFolders.SelectMany(parent => parent.AttachmentFolder)
.FirstOrDefault(child => child.FID == "835A09A2-9D60-46CC-A2BE-D4CBC4C81860");
another picture to better understand
in fact, I get a list with many elements and should scroll it all , even in responsive manner to be able to return the object that corresponds to that AttachmentFolders FID .
class structure:
public class AttachmentFolders
{
public int id { get; set; }
public String FID { get; set; }
public String Name { get; set; }
public String CPID { get; set; }
public String ParentFID { get; set; }
public List<Attachment> Attachments { get; set; }
public List<AttachmentFolders> AttachmentFolder { get; set; }
}
public class Attachment
{
public int id { get; set; }
public String ATID { get; set; }
public String Name { get; set; }
public String CreatorID { get; set; }
public String FID { get; set; }
public String Extension { get; set; }
public String Description { get; set; }
public int Status { get; set; }
public String CPID { get; set; }
public int FileSize { get; set; }
public DateTime CreationDate { get; set; }
public DateTime ModifiedDate { get; set; }
public int AttachmentType { get; set; }
public int ValidityType { get; set; }
public List<Revisions> Revisions { get; set; }
public String AWID { get; set; }
public String WAID { get; set; }
public String WatermarkPositions { get; set; }
public Boolean Serveroffline { get; set; }
public Boolean IsFavourite { get; set; }
public DateTime LastOpenDate { get; set; }
public int Priority { get; set; }
public String CreatorFirstName { get; set; }
public String CreatorLastName { get; set; }
public String ModifiedByFirstName { get; set; }
public String ModifiedByLastName { get; set; }
public String[] Capabilities { get; set; }
}
Thank you all.
You can write something like the SelectDeep extension as in this Marc's answer: Expressing recursion in LINQ
and then use it in your code instead of SelectMany:
AttachmentFolders child = companyList[0].AttachmentFolders
.SelectDeep(parent => parent.AttachmentFolder)
.FirstOrDefault(child => child.FID == "835A09A2-9D60-46CC-A2BE-D4CBC4C81860");
The SelectDeep method looks as follows:
public static class EnumerableExtensions
{
public static IEnumerable<T> SelectDeep<T>(
this IEnumerable<T> source, Func<T, IEnumerable<T>> selector) {
foreach (T item in source) {
yield return item;
foreach (T subItem in SelectDeep(selector(item), selector)) {
yield return subItem;
}
}
}
}
This is a typical recursion case. You could try searching a flattened tree structure, as done in this or this answer.
If you experience slow performance of this solution, I would think about creating a helper Dictionary<string, AttachmentFolders> object, which would hold all (sub)folder references for quick access, e.g.
IEnumerable<AttachmentFolders> Flatten(AttachmentFolders f)
{
var fs = new[] { f };
return f.Children == null? fs : fs.Concat(f.Children.SelectMany(Flatten));
}
Dictionary<string, AttachmentFolders> GenerateCache(AttachmentFolders firstFolder)
{
return Flatten(firstFolder).ToDictionary(f => f.FID, f => f);
}
Then, one-time at start:
Dictionary<string, AttachmentFolders> Cache = GenerateCache(firstFolder);
And each time a request is made:
if(Cache.ContainsKey(fid)) return Cache[fid];
else throw new Exception("Handle not found FID here");
I'm trying to fetch a name from one iList into another where they both contain the same ID.
public class Notifications
{
[JsonProperty("note_id")]
public int note_id { get; set;}
[JsonProperty("sender_id")]
public int sender_id { get; set;}
public string sender_name { get; set; }
[JsonProperty("receiver_id")]
public int receiver_id { get; set; }
[JsonProperty("document_id")]
public int document_id { get; set; }
[JsonProperty("search_name")]
public string search_name { get; set; }
[JsonProperty("unread")]
public int unread { get; set; }
}
public class CompanyDirectory
{
[JsonProperty("contact_id")]
public int contact_id { get; set; }
[JsonProperty("first_name")]
public string first_name { get; set; }
[JsonProperty("second_name")]
public string second_name { get; set; }
[JsonProperty("extension")]
public string extension { get; set; }
[JsonProperty("direct_dial")]
public string direct_dial { get; set; }
[JsonProperty("job_title")]
public string job_title { get; set; }
[JsonProperty("company_id")]
public int company_id { get; set; }
}
Then i'm doing the following, the lists both get populated fine. The weird bit is i'm getting errors saying that where I do CompanyDir.first_name that the property doesn't exist, where it clearly does?:
// This occurs just after the class declaration
public IList<Notifications> Notes;
public IList<CompanyDirectory> CompanyDir;
// Ignore that these both use the same string they're created at different parts of the load process
CompanyDir = JsonConvert.DeserializeObject<IList<CompanyDirectory>>(responseString);
Notes = JsonConvert.DeserializeObject<IList<Notifications>>(responseString);
// Now I thought I should be able to do
foreach(var s in Notes){
var thename = CompanyDir.first_name.Where(contact_id.Contains(s.sender_id))
}
You should look up LinQ and Lambda expressions:
var firstNames = CompanyDir.Where(c => c.contact_id == s.sender_id)
.Select(c => c.first_name)
.ToList();
Now you have a list of firstnames. A list, because there may be zero or more hits for your Where constraint.