Traverse n-level parent child list C# - list

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;
}

Related

Joining 2 lists with condition

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) });

model item passed into dictionary is of type 'system.Collections.Generic.List'1[System.String]',but dictionary is model B

I am trying to create a create combobox with performcallback, but I got the error. here this error "the model item passed into dictionary is of type 'system.Collections.Generic.Lost'1[System.String]', but this dix=ctionary requires a model item of type 'DIS_iDealer.Models.SalesMonitoringModel'"
I don't know which code exactly I need to paste but this is what I have:
view combobox :
#model DIS_iDealer.Models.SalesMonitoringModel
#Html.DevExpress().ComboBoxFor(m => m.mpmGroupLine.DESCRIPTION, settings =>
{
settings.Name = "Desc_ID_CB";
settings.Properties.IncrementalFilteringMode = IncrementalFilteringMode.Contains;
settings.Properties.DropDownStyle = DropDownStyle.DropDownList;
settings.CallbackRouteValues = new { Controller = "Report", Action = "cbPartialCategoryDetail" };
settings.Properties.CallbackPageSize = 50;
settings.Properties.ValueField = "DESCRIPTION";
settings.Properties.TextField = "DESCRIPTION";
settings.Width = 150;
settings.SelectedIndex = 0;
settings.Properties.ClientSideEvents.BeginCallback = "function(s,e){e.customArgs['group_Id'] = Category_Id_CB.GetValue()}";
settings.Properties.ValidationSettings.ErrorTextPosition = ErrorTextPosition.Right;
settings.Properties.ValidationSettings.ErrorDisplayMode = ErrorDisplayMode.ImageWithText;
settings.Properties.ValidationSettings.Display = Display.Dynamic;
}).BindList((List<string>)new DIS_iDealer.DataAccess.SalesMonitoringDAC().GetProductGroupDetail(Model.mpmGroupLine.GROUPID).ToList()).GetHtml()
controller :
namespace DIS_iDealer.Controllers
{
public class ReportController : BaseController
{
[HttpGet]
public ActionResult Report_SalesMonitoring_2()
{
SalesMonitoringModel mode = new SalesMonitoringModel();
//MPMPRODUCTGROUPLINE itemB = new MPMPRODUCTGROUPLINE();
/*List<string> mpmCate = mode.GetProductGroup();
if (mpmCate != null)
{
itemB.DESCRIPTION = mode.mpmGroupLine.DESCRIPTION;
}*/
ReportModels modelReport = new ReportModels();
if (TempData["ReportSalesMonitoring2"] != null)
{
modelReport = (ReportModels)TempData["ReportSalesMonitoring2"];
string reportParam = string.Empty;
foreach (string item in modelReport.ParameterReport)
{
reportParam += item;
}
ViewBag.IframeURL = modelReport.WebURL + reportParam;
}
return View(mode);
}
[ValidateInput(false)]
public ActionResult cbPartialCategoryDetail(string group_Id)
{
//SalesMonitoringModel model = new SalesMonitoringModel();
SalesMonitoringDAC model = new SalesMonitoringDAC();
List<string> itemDetail = model.GetProductGroupDetail(group_Id);
return PartialView("_cbPartialCategoryDetail", itemDetail);
}
}
}
Please let me know if you need more info. Thanks.

Display certain list when clicking on different links in a view

I need to display a different list each time I click on different links in my view. Help would be appreciated :)
My controller:
public class HomeController : Controller
{
Teams tm = new Teams();
Details det = new Details();
public ActionResult Index()
{
var model = new List<Teams>();
model.Add(new Teams { Name = "Manchester United", NickName = "The Red Devils", HomeGround = "Old Trafford", Founded = 1878 });
model.Add(new Teams { Name = "Liverpool", NickName = "The reds", HomeGround = "Anfield", Founded = 1870 });
return View(model);
}
public ActionResult About()
{
var title = new List<Details>();
title.Add(new Details { MajorHonours = 62, PremLeague = 20, FACup = 11, LeagueCup = 4, UEFA = 3 });
title.Add(new Details { MajorHonours = 60, PremLeague = 18, FACup = 7, LeagueCup = 8, UEFA = 5 });
return View();
}
My view with the links:
#model IEnumerable<Standings.Models.Teams>
#{
ViewBag.Title = "Standings";
}
<h1>List of teams</h1>
#foreach (var item in Model)
{
<div>
#Html.ActionLink(#item.Name, "About") (#item.NickName, #item.HomeGround, #item.Founded)
<hr />
</div>
}
My model:
public class Details
{
public int MajorHonours { get; set; }
public int PremLeague { get; set; }
public int FACup { get; set; }
public int LeagueCup { get; set; }
public int UEFA { get; set; }
}
And I have a clean View with the name About that the list needs to be displayed on

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.