Joining 2 lists with condition - list

I want to join 2 lists. Students and Persons.
Both Student and Person has id and a name variable, plus Student has another variable called isStudying. I want to join all Students to Person with the isStudying variable.
var persons = new Person { id = 1, name = "John" };
var persons = new Person { id = 2, name = "Ace" };
var persons = new Person { id = 3, name = "Mike" };
var persons = new Person { id = 4, name = "Yob" };
var persons = new Person { id = 5, name = "Ken" };
var students = new Student { id = 2, name = "Ace", isStudying=true };
var students = new Student { id = 3, name = "Mike", isStudying = true };
var students = new Student { id = 5, name = "Ken", isStudying = true };
persons.Addrange(students.where(student.id.contain(persons.id)));

Here is full solution implemented in linq, used inheritance
class Person
{
public int id { get; set; }
public string name { get; set; }
}
class Student : Person
{
public bool isStudying { get; set; }
}
void Main()
{
var person1 = new Person { id = 1, name = "John" };
var person2 = new Person { id = 2, name = "Ace" };
var person3 = new Person { id = 3, name = "Mike" };
var person4 = new Person { id = 4, name = "Yob" };
var person5 = new Person { id = 5, name = "Ken" };
var persons = new List<Person> { person1, person2, person3, person4, person5 };
var student1 = new Student { id = 2, name = "Ace", isStudying = true };
var student2 = new Student { id = 3, name = "Mike", isStudying = true };
var student3 = new Student { id = 5, name = "Ken", isStudying = true };
var students = new List<Student> { student1, student2, student3 };
var personsRes = persons.Where(y => students.Select(x => x.id).Contains(y.id));
Console.WriteLine(personsRes);
}

Try This:
public class Person
{
public int id { get; set; }
public string name { get; set; }
}
public class Student
{
public int id { get; set; }
public string name { get; set; }
public bool isStudying { get; set; }
}
var persons = new List<Person> { new Person { id = 1, name = "John" },
new Person { id = 2, name = "Ace" },
new Person { id = 3, name = "Mike"},
new Person { id = 4, name = "Yob" },
new Person { id = 5, name = "Ken" } };
var students = new List<Student> { new Student { id = 2, name = "Ace", isStudying = true },
new Student { id = 3, name = "Mike", isStudying = true },
new Student { id = 5, name = "Ken", isStudying = true } };
var allPersons = (from p in persons
join s in students on new { first = p.id } equals new { first = s.id } into sjoin
from slj in sjoin.DefaultIfEmpty()
select new
{
id = p.id,
name = p.name,
isStudying = (slj != null ? (slj.isStudying ? "TRUE" : "FALSE") : string.Empty)
}).ToList();

For future readers' reference, one simple answer which I provided in comments using LINQ is:
With anonymous types:
persons.Select(p => new { p.id, p.name, students.Any(s => s.id == p.id && s.isStudying) });
Using a custom class (the Student class can actually be re-used):
persons.Select(p => new Student { id = p.id, name = p.name, isStudying = students.Any(s => s.id == p.id && s.isStudying) });

Related

Creating combinations sku product C#

I've to figure out how to generate SKUs for a product with a certain number (x) of attributes and each attribute has a certain number (y) of values. For example:
A t-shirt has the following attributes:
Color
Size
Gender
Sleeve
And the values for those attributes are:
Color: Red, White, Blue
Size: S, M, L, XL
Gender: M, F
Sleeve: Short, Long
I need to create a SKU for each unique combination e.g. SKU #: 1234 for Small, Red, Male w/ short sleeves, SKU #: 2345 for Small, Red, Male, Long Sleeve.
My Class:
public class Sku
{
public int Id { get; set; }
public int ProductId { get; set; }
public string Name { get; set; }
public List<SkuDetail> SkuDetails { get; set; };
}
public class SkuDetail
{
public int Id { get; set; }
public int SkuId { get; set; }
public string Name { get; set; }
}
Demo data:
var skus = new List<Sku>();
skus.Add(new Sku
{
Name = "Size",
SkuDetails = new List<SkuDetail>
{
new SkuDetail {Name = "S"}, new SkuDetail {Name = "M"},
new SkuDetail {Name = "L"}, new SkuDetail {Name = "XL"}, new SkuDetail {Name = "XXL"}
}
});
skus.Add(new Sku
{
Name = "Color",
SkuDetails = new List<SkuDetail>
{
new SkuDetail {Name = "Red"}, new SkuDetail {Name = "White"},
new SkuDetail {Name = "Black"}
}
});
skus.Add(new Sku
{
Name = "Style",
SkuDetails = new List<SkuDetail>
{new SkuDetail {Name = "Modern"}, new SkuDetail {Name = "classic"}}
});
I'd like to use the most efficient approach but I can only think of nested foreach statements for this. I could use some help with the logic here.

Traverse n-level parent child list C#

I have a parent-child list. It can be of n-level.
I need each item within this hierarchy.
I am using 'foreach' loop and recursive function but it's not working.
I have went through other solutions at 'stackoverflow' but none of them worked for me.
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public int ParentId { get; set; }
private List<Item> children = new List<Item>();
public List<Item> Children
{
get { return children; }
set { children = value; }
}
}
List<Item> test = new List<Item>();
test.Add(new Item { Id = 1, Name = "Root1", ParentId = -1 });
test[0].Children.Add(new Item { Id = 4, Name = "child-1-Root1", ParentId = 1 });
test[0].Children[0].Children.Add(new Item { Id = 10, Name = "grandchild-1-Root1", ParentId = 4 });
test[0].Children.Add(new Item { Id = 5, Name = "child-2-Root1", ParentId = 1 });
test.Add(new Item { Id = 2, Name = "Root2", ParentId = -1 });
test[1].Children.Add(new Item { Id = 6, Name = "child-1-Root2", ParentId = 2 });
test[1].Children.Add(new Item { Id = 7, Name = "child-2-Root2", ParentId = 2 });
test.Add(new Item { Id = 3, Name = "Root3", ParentId = -1 });
test[2].Children.Add(new Item { Id = 8, Name = "child-1-Root3", ParentId = 3 });
test[2].Children.Add(new Item { Id = 9, Name = "child-2-Root3", ParentId = 3 });
The solution is:
public static Find()
{
foreach (var item in test)
{
FindRecursively(item, item.Name);
}
}
public static Item FindRecursively(Item node, string name)
{
if (node == null)
return null;
if (node.Name == name)
Console.WriteLine(node.Name);
foreach (var child in node.Children)
{
var found = FindRecursively(child, child.Name);
}
return null;
}

Record system list of customers each with list of cars

I am working on a simple simulation for a mechanic record system where it will contain a list of customers and their details; each having a list of cars which they own. Every visit will also be recorded.
Customer: Name, address, list of cars (with make, model and reg number)
Visit: Date, Owner, Car, Description on work done, Date of next visit
In the main method i need to simulate the creation of two clients with each having 5 cars each. The data will be hard coded. Then need to add 7 visit and display all info.
class Human
{
int id;
public int Id
{
get { return id; }
set { id = value; }
}
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private string address;
public string Address
{
get { return address; }
set { address = value; }
}
}
class Customer : Human
{
public LinkedList<Car> Cars = new LinkedList<Car>();
public Customer()
{
}
}
public class Visit
{
public int visitId { get; set; }
public DateTime DateTimeVisited { get; set; }
public string customer { get; set; }
public string Discussion { get; set; }
public DateTime NextDateTimetoVisit { get; set; }
}
class Mechanic :Human
{
public LinkedList<Customer> customerDetails;
public LinkedList<Visit> visitDetails;
public LinkedList<Car> carDetails;
public Mechanic()
{
customerDetails = new LinkedList<Customer>();
visitDetails = new LinkedList<Visit>();
carDetails = new LinkedList<Car>();
}
public void AddCustomer(Customer c)
{
customerDetails.AddLast(c);
}
public void AddVisit(Visit v)
{
visitDetails.AddLast(v);
}
public LinkedList<Customer> ViewCustomer()
{
return customerDetails;
}
public LinkedList<Visit> ViewVisit()
{
return visitDetails;
}
public void AddCar(Car car)
{
carDetails.AddLast(car);
}
}
//Main
//Create customer
Customer customer1 = new Customer();
Customer customer2 = new Customer();
customer1.Id = 1;
customer1.Name = "Brandon Spiteri";
customer1.Address = "22, St. George's St. B'bugia";
mech1.AddCustomer(customer1);
Car car1 = new Car();
car1.carmake = "Hyundai";
car1.carmodelnum = "HJ30NAEJJ";
car1.carregnum = "BAH 864";
car1.Id = 1; //check
mech1.AddCar(car1);
//mech1.AddCar(car1);
Car car2 = new Car();
car2.carmake = "Citroen";
car2.carmodelnum = "HJ30NAEJJ";
car2.carregnum = "IBE 554";
car2.Id = 1;
mech1.AddCar(car2);
Car car3 = new Car();
car3.carmake = "Toyota";
car3.carmodelnum = "HJ30NAEJJ";
car3.carregnum = "DAP 691";
car3.Id = 1;
mech1.AddCar(car3);
Car car4 = new Car();
car4.carmake = "Nissan";
car4.carmodelnum = "HJ30NAEJJ";
car4.carregnum = "EBD 482";
car4.Id = 1;
mech1.AddCar(car4);
Car car5 = new Car();
car5.carmake = "Rover";
car5.carmodelnum = "HJ30NAEJJ";
car5.carregnum = "BAD 505";
car5.Id = 1;
mech1.AddCar(car5);
customer2.Id = 2;
customer2.Name = "George Spiteri";
customer2.Address = "6, Dun A. Gambin St. Santa Lucija";
mech1.AddCustomer(customer2);
Car car6 = new Car();
car6.carmake = "Mercedes";
car6.carmodelnum = "HJ30NAEJJ";
car6.carregnum = "BAH 864";
car6.Id = 2;
mech1.AddCar(car6);
Car car7 = new Car();
car7.carmake = "BMW";
car7.carmodelnum = "HJ30NAEJJ";
car7.carregnum = "EFG 426";
car7.Id = 2;
mech1.AddCar(car7);
Car car8 = new Car();
car8.carmake = "Peugeot";
car8.carmodelnum = "HJ30NAEJJ";
car8.carregnum = "IHJ 376";
car8.Id = 2;
mech1.AddCar(car8);
Car car9 = new Car();
car9.carmake = "Mazda";
car9.carmodelnum = "HJ30NAEJJ";
car9.carregnum = "ADL 693";
car9.Id = 2;
mech1.AddCar(car9);
Car car10 = new Car();
car10.carmake = "Ford";
car10.carmodelnum = "HJ30NAEJJ";
car10.carregnum = "RGJ 486";
car10.Id = 2;
mech1.AddCar(car10);
When I debug to see if the cars are under the particular customer, they seem to be declared separately and the customers have no cars. Also is the Visit class implemented correctly? Where am i going wrong? thanks
Move all lists as well as the method AddCar to the base class like this:
class Human
{
public LinkedList<Customer> customerDetails;
public LinkedList<Visit> visitDetails;
public LinkedList<Car> carDetails;
public void AddCar(Car car)
{
carDetails.AddLast(car);
}
...
}
class Customer:public Human
{
...
}

RavenDB MultiMapReduce Sum not returning the correct value

Sorry for this lengthy query, I decided to add the whole test so that it will be easier for even newbies to help me with this total brain-melt.
The using directives are:
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Raven.Client;
using Raven.Client.Embedded;
using Raven.Client.Indexes;
Please leave feedback if I'm too lengthy, but what could possibly go wrong if I add a complete test?
[TestFixture]
public class ClicksByScoreAndCardTest
{
private IDocumentStore _documentStore;
[SetUp]
public void SetUp()
{
_documentStore = new EmbeddableDocumentStore {RunInMemory = true}.Initialize();
_documentStore.DatabaseCommands.DisableAllCaching();
IndexCreation.CreateIndexes(typeof (ClicksBySearchAndProductCode).Assembly, _documentStore);
}
[TearDown]
public void TearDown()
{
_documentStore.Dispose();
}
[Test]
public void ShouldCountTotalLeadsMatchingPreference()
{
var userFirst = new User {Id = "users/134"};
var userSecond = new User {Id = "users/135"};
var searchFirst = new Search(userFirst)
{
Id = "searches/24",
VisitId = "visits/63"
};
searchFirst.Result = new Result();
searchFirst.Result.Rows = new List<Row>(
new[]
{
new Row {ProductCode = "CreditCards/123", Score = 6},
new Row {ProductCode = "CreditCards/124", Score = 4}
});
var searchSecond = new Search(userSecond)
{
Id = "searches/25",
VisitId = "visits/64"
};
searchSecond.Result = new Result();
searchSecond.Result.Rows = new List<Row>(
new[]
{
new Row {ProductCode = "CreditCards/122", Score = 9},
new Row {ProductCode = "CreditCards/124", Score = 4}
});
var searches = new List<Search>
{
searchFirst,
searchSecond
};
var click = new Click
{
VisitId = "visits/64",
ProductCode = "CreditCards/122",
SearchId = "searches/25"
};
using (var session = _documentStore.OpenSession())
{
foreach (var search in searches)
{
session.Store(search);
}
session.Store(click);
session.SaveChanges();
}
IList<ClicksBySearchAndProductCode.MapReduceResult> clicksBySearchAndProductCode = null;
using (var session = _documentStore.OpenSession())
{
clicksBySearchAndProductCode = session.Query<ClicksBySearchAndProductCode.MapReduceResult>(ClicksBySearchAndProductCode.INDEX_NAME)
.Customize(x => x.WaitForNonStaleResults()).ToArray();
}
Assert.That(clicksBySearchAndProductCode.Count, Is.EqualTo(4));
var mapReduce = clicksBySearchAndProductCode
.First(x => x.SearchId.Equals("searches/25")
&& x.ProductCode.Equals("CreditCards/122"));
Assert.That(mapReduce.Clicks,
Is.EqualTo(1));
}
}
public class ClicksBySearchAndProductCode :
AbstractMultiMapIndexCreationTask
<ClicksBySearchAndProductCode.MapReduceResult>
{
public const string INDEX_NAME = "ClicksBySearchAndProductCode";
public override string IndexName
{
get { return INDEX_NAME; }
}
public class MapReduceResult
{
public string SearchId { get; set; }
public string ProductCode { get; set; }
public string Score { get; set; }
public int Clicks { get; set; }
}
public ClicksBySearchAndProductCode()
{
AddMap<Search>(
searches =>
from search in searches
from row in search.Result.Rows
select new
{
SearchId = search.Id,
ProductCode = row.ProductCode,
Score = row.Score.ToString(),
Clicks = 0
});
AddMap<Click>(
clicks =>
from click in clicks
select new
{
SearchId = click.SearchId,
ProductCode = click.ProductCode,
Score = (string)null,
Clicks = 1
});
Reduce =
results =>
from result in results
group result by
new { SearchId = result.SearchId, ProductCode = result.ProductCode }
into g
select
new
{
SearchId = g.Key.SearchId,
ProductCode = g.Key.ProductCode,
Score = g.First(x => x.Score != null).Score,
Clicks = g.Sum(x => x.Clicks)
};
}
}
public class User
{
public string Id { get; set; }
}
public class Search
{
public string Id { get; set; }
public string VisitId { get; set; }
public User User { get; set; }
private Result _result = new Result();
public Result Result
{
get { return _result; }
set { _result = value; }
}
public Search(User user)
{
User = user;
}
}
public class Result
{
private IList<Row> _rows = new List<Row>();
public IList<Row> Rows
{
get { return _rows; }
set { _rows = value; }
}
}
public class Row
{
public string ProductCode { get; set; }
public int Score { get; set; }
}
public class Click
{
public string VisitId { get; set; }
public string SearchId { get; set; }
public string ProductCode { get; set; }
}
My problem here is that I expect Count to be one in that specific test, but it just doesn't seem to add the Clicks in the Click map and the result is 0 clicks. I'm totally confused, and I'm sure that there is a really simple solution to my problem, but I just can't find it..
..hope there is a week-end warrior out there who can take me under his wings.
Yes, it was a brain-melt, for me non-trivial, but still. The proper reduce should look like this:
Reduce =
results =>
from result in results
group result by
new { SearchId = result.SearchId, ProductCode = result.ProductCode }
into g
select
new
{
SearchId = g.Key.SearchId,
ProductCode = g.Key.ProductCode,
Score = g.Select(x=>x.Score).FirstOrDefault(),
Clicks = g.Sum(x => x.Clicks)
};
Not all Maps had the Score set to a non-null-value, and therefore my original version had a problem with:
Score = g.First(x => x.Score != null).Score
Mental note, use:
Score = g.Select(x=>x.Score).FirstOrDefault()
Don't use:
Score = g.First(x => x.Score != null).Score

MultiMap / Reduce - Counts = 0?

I want to create an index for a query, I want to return to my view a list of Audio items along with statistics for these items, which are TotalDownloads & TotalPlays.
Here are my relevant docs:
Audio
- Id
- ArtistName
- Name
AudioCounter
- AudioId
- Type
- DateTime
Here is my current Index:
public class AudioWithCounters : AbstractMultiMapIndexCreationTask<AudioWithCounters.AudioViewModel>
{
public class AudioViewModel
{
public string Id { get; set; }
public string ArtistName { get; set; }
public string Name { get; set; }
public int TotalDownloads { get; set; }
public int TotalPlays { get; set; }
}
public AudioWithCounters()
{
AddMap<Audio>(audios => from audio in audios
select new
{
Id = audio.Id,
ArtistName = audio.ArtistName,
Name = audio.Name,
TotalDownloads = 0,
TotalPlays = 0
});
AddMap<AudioCounter>(counters => from counter in counters
where counter.Type == Core.Enums.Audio.AudioCounterType.Download
select new
{
Id = counter.AudioId,
ArtistName = (string)null,
Name = (string)null,
TotalDownloads = 1,
TotalPlays = 0
});
AddMap<AudioCounter>(counters => from counter in counters
where counter.Type == Core.Enums.Audio.AudioCounterType.Download
select new
{
Id = counter.AudioId,
ArtistName = (string)null,
Name = (string)null,
TotalDownloads = 0,
TotalPlays = 1
});
Reduce = results => from result in results
group result by result.Id
into g
select new
{
Id = g.Key,
ArtistName = g.Select(x => x.ArtistName).Where(x => x != null).First(),
Name = g.Select(x => x.Name).Where(x => x != null).First(),
TotalDownloads = g.Sum(x => x.TotalDownloads),
TotalPlays = g.Sum(x => x.TotalPlays)
};
}
}
However, my TotalDownloads & TotalPlays are always 0 even though there should be data in there. What am I doing wrong?
In the reduce function, replace .First() with .FirstOrDefault(), then it works.
Besides that, there is a typo in the second map-function, because you are filtering on the same AudioCounterType.Download.