how to loop over generic List and group per 3 i

2020-07-27 03:02发布

问题:

I want to loop over a generic list of MemberProfiles:

List<MemberProfile> jobseekers    

, and group the items in a <div class='group'>tag. Every <div class="group"> should contain 3 jobseekers like this:

<div class="group">
    <div class="jobseeker">
        ...data jobseeker
    </div>
</div>

I tried different methods on generic list, like .skip() and .take() but I'm not succeeding in implementing this scenario.

My code looks like this:

foreach (MemberProfile jobseekerProfile in Jobseekers)
{
    if (jobseekerProfile != null)
    {
        Label lblJobseeker = new Label();
        StringBuilder sbJobseeker = new StringBuilder();
        sbJobseeker.Append(string.Format("<p><strong>{0}&nbsp;{1}</strong><br />", jobseekerProfile.FirstName, jobseekerProfile.LastName));
        XPathNodeIterator preValues = library.GetPreValues(1362);
        preValues.MoveNext();
        XPathNodeIterator iterator2 = preValues.Current.SelectChildren("preValue", "");
        while (iterator2.MoveNext())
        {
            if (jobseekerProfile.JobType == iterator2.Current.GetAttribute("id", ""))
            {
                sbJobseeker.Append(string.Format("looking for a {0}<br />", iterator2.Current.Value));
            }
        }
        XPathNodeIterator iterator3 = library.GetPreValues(1363);
        iterator3.MoveNext();
        XPathNodeIterator iterator4 = iterator3.Current.SelectChildren("preValue", "");
        StringBuilder sbJobExperience = new StringBuilder();
        string[] strJobExperience = jobseekerProfile.JobExperience.Split(new char[] { ',' });
        int counter = 1;
        while (iterator4.MoveNext())
        {
            if (jobseekerProfile.JobExperience.Contains(iterator4.Current.GetAttribute("id", "")))
            {
                if (counter != strJobExperience.Count<string>())
                {
                    sbJobExperience.Append(string.Format("{0}, ", iterator4.Current.Value));
                    counter++;
                }
                else
                {
                    sbJobExperience.Append(string.Format("{0}", iterator4.Current.Value));
                }
            }
        }
        sbJobseeker.Append(string.Format("Fields of experience: {0}<br />", sbJobExperience.ToString()));
        sbJobseeker.Append(string.Format("Years of experience: {0}<br />", jobseekerProfile.YearsExperience));
        sbJobseeker.Append(string.Format("Country: {0}<br />", jobseekerProfile.Country));
        sbJobseeker.Append(string.Format("<form name='frmSelect' action='/selectjobcandidate.aspx' method='post'><input type='hidden' name='username' value='{0}' /><input type='submit' value='select candidate' /></form>", jobseekerProfile.UserName));
        lblJobseeker.Text = sbJobseeker.ToString();
        phListJobseekers.Controls.Add(lblJobseeker);
    }
}    

can someone put me on the right track to implement this scenario?

回答1:

for (var i = 0; i < Jobseekers.Count; i += 3)
{
    foreach (MemberProfile jobseekerProfile in Jobseekers.Skip(i).Take(3))
    {

    }
}

Is this what you are after?



回答2:

Since you seem to want to do it with linq, here we go:

var tagged = Jobseekers.Select((x, i) => new { x, i });
var grouped = tagged.ToLookup(t => (t.i - 1) / 3, t => t.x);

foreach (var group in grouped)
{
    Console.WriteLine("Group:");
    foreach (var item in group)
    {
        Console.WriteLine(item);
    }
}


回答3:

From the following answer : Split List into Sublists with LINQ

public static List<List<MemberProfile>> Split(List<MemberProfile> source)
{
    return  source
        .Select((x, i) => new { Index = i, Value = x })
        .GroupBy(x => x.Index / 3)
        .Select(x => x.Select(v => v.Value).ToList())
        .ToList();
}

See other answers as well



回答4:

Your question isn't completely clear, but it appears that you want to split your jobseekers list into groups of 3 elements each, and then perform some manipulation on each group of 3 to get some HTML snippet, so the output is a sequence of HTML snippets.

Let's assume that jobseekers always has a multiple of 3 elements. If it doesn't always have 3 elements, this solution will leave the last group with the remainder of the elements, and you can filter out that group by dropping any group with fewer than 3 elements (that Where would go just after the GroupBy). With LINQ:

IEnumerable<string> htmlSnippets = jobseekers
    .Zip(Enumerable.Range(0, jobseekers.Count), Tuple.Create)
    .GroupBy(tup => tup.Item2 / 3)
    .Select(GenerateHtmlString);
string combinedHtmlString = string.Join(string.Empty, htmlSnippets);

public string GenerateHtmlString(IEnumerable<MemberProfile> profiles)
{
    return string.Format(@"<div class=""jobseeker"">{0}</div>",
        // The question doesn't specify how the 3 jobseekers are rendered in HTML
        );
}