santosh singh
santosh singh

Reputation: 28652

combine foreach loop and linq query into single linq query

I have summarized my problem in following c# code snippet.In which I am filtering hotel by review.we get user review from user in the from of comma separated value.Currently I am looping through the user review and combining each result into single result. Now,I want to write loop and linq query into single linq query.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LinqST
{
    public class Hotel
    {

        public string Name { get; set; }
        public int Review { get; set; }

    }
    public class DAL
    {
        public static List<Hotel> Get()
        {
            return new List<Hotel>()
            {
                new Hotel{Name="Hotel1",Review=4},
                new Hotel{Name="Hotel2",Review=2},
                new Hotel{Name="Hotel3",Review=2},
                new Hotel{Name="Hotel4",Review=3},
                new Hotel{Name="Hotel5",Review=5},
                new Hotel{Name="Hotel6",Review=5},
                new Hotel{Name="Hotel61",Review=4},
                new Hotel{Name="Hotel6",Review=4}
            };
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var filterHotel = "3,4";
            var tempList = new List<Hotel>();
            foreach (var item in  Array.ConvertAll(filterHotel.Split(','), s => int.Parse(s)))
            {
                var list = DAL.Get().Where(x => x.Review == item);
                tempList = tempList.Union(list).ToList();
            }
        }
    }
}

Upvotes: 1

Views: 1657

Answers (3)

Jon Skeet
Jon Skeet

Reputation: 1500595

It sounds like you've got a join, basically:

var ratings = filterHotel.Split(',').Select(text => int.Parse(text)).Distinct();
var list = DAL.Get()
              .Join(ratings, hotel => hotel.Review, rating => rating,
                    (hotel, rating) => hotel)
              .ToList();

EDIT: As requested, if having a single statement is more valuable to you than readability:

var list = DAL.Get()
              .Join(filterHotel.Split(',').Select(text => int.Parse(text)).Distinct(),
                    hotel => hotel.Review,
                    rating => rating,
                    (hotel, rating) => hotel)
              .ToList();

Or as a query expression:

var list = (from hotel in DAL.Get()
            join rating in filterHotel.Split(',')
                                      .Select(text => int.Parse(text))
                                      .Distinct()
            on hotel.review equals rating
            select hotel).ToList();

Upvotes: 3

Akrem
Akrem

Reputation: 4652

you can use this :

tempList = Array.ConvertAll(filterHotel.Split(','), int.Parse)
                .Select(item => DAL.Get().Where(x => x.Review == item))
                .Aggregate(tempList, (current, list) => current.Union(list).ToList());

result by resharper

Upvotes: 2

p.s.w.g
p.s.w.g

Reputation: 149020

Try using Contains:

var filteredIds = Array.ConvertAll(filterHotel.Split(','), int.Parse); // or filterHotel.Split(',').Select(int.Parse);
var list = DAL.Get().Where(x => filteredIds.Contains(x.Review));

Upvotes: 4

Related Questions