PDA

View Full Version : سوال: جستجو پیشرفته از لیست باکس



dele_ghamgin_2008
شنبه 15 فروردین 1394, 13:40 عصر
سلام . من یک لیست باکس دارم که آیتم های آن شامل عبارات زیر می باشد :

قیمت بهترین سیب ایرانی
قیمت انواع سیب ایرانی
مرکز تولید سیب ایرانی
فروش سیب قرمز تازه
انواع سیب سبز ایرانی
تولید سیب قرمز اعلا
قیمت فروش سیب ایرانی
قیمت تولید سیب برای ایرانی ها

حالا یه تکست باکس دارم ، میخوام هرچی که توی تکست باکس نوشتم برایم سرچ انجام بده از لیست باکس ولی با قاعده زیر :
مثلا من میخوام از بین آیتم های لیست باکس ، به دنبال عبارت قیمت سیب ایرانی بگردم . یعنی هر آیتمی که توش این کلمات وجود داشت رو برام استخراج کنه : این سه کلمه شامل : قیمت ، سیب ، ایرانی می شه.
یعنی وقتی این عبارت رو توی تکست باکس نوشتم ، میخوام که در یک لیست باکس دیگر مقادیر جستجو شده نمایش داده شود : یعنی نتیجه جستجو باید بشود :

قیمت بهترین سیب ایرانی
قیمت انواع سیب ایرانی
قیمت فروش سیب ایرانی
قیمت تولید سیب برای ایرانی ها

لطفا اگر راهی به ذهن شما می رسد اطلاع دهید ، من جستجو یک کلمه رو بلدم ، ولی اینگونه جستجو رو نمیدونم باید چیکار کنم . جستجو یک کلمه رو در زیر براتون می ذارم شاید کمک کند :
lstOne.Items.Clear(); //جستجو از بین آیتم های لیست باکس
List<string> search = new List<string> { txtSearchItem.Text };
List<string> finds = new List<string>();
foreach (var item in LstAll.Items.Cast<string>())
{
foreach (var itemIn in search)
{
if (item.Contains(itemIn))
{
finds.Add(item);
}
}
}
lstOne.Items.AddRange(finds.ToArray());
lblOne.Text = lstOne.Items.Count.ToString();

am_al_59
شنبه 15 فروردین 1394, 16:25 عصر
کدش این میشه

search.Where(src => words.All(word => src.Contains(word)));

در این کد words کلماتی هست که میخوای جستجو بر اساس اونها انجام بشه
search هم کل آیتم هایی هست که میخواهی جستجو در آنها انجام بشه

dele_ghamgin_2008
یک شنبه 16 فروردین 1394, 00:41 صبح
کدش این میشه

search.Where(src => words.All(word => src.Contains(word)));

در این کد words کلماتی هست که میخوای جستجو بر اساس اونها انجام بشه
search هم کل آیتم هایی هست که میخواهی جستجو در آنها انجام بشه

واقعیتش اصلا متوجه نشدم . یعنی باید چجوری بهش بفهمونم که words همون عبارت منه ؟ یعنی اینطوری بنویسیم ؟
string words = txtsearch.text
بعدش برای اون قسمت search باید چجوری این همه آیتم رو توش تعریف کنم ؟ ممنون میشم راهنمایی کنید. من اینجوری نوشتم ولی اتفاق خاصی نیوفتاد ! چجوری به لیست باکس بعدی منتقل میشه ؟

var search = LstAll.Items.Cast<string>().ToList(); string words = txtTag.Text;
search.Where(src => words.All(word => src.Contains(word)));

am_al_59
یک شنبه 16 فروردین 1394, 00:47 صبح
شما یک یا چند کلمه داری که میخوای هر عبارتی که دارای یکی از اونها بود پیدا بشه
برای این کار مثلاً شما کلماتت طبق گفته خوذتون اینه

قیمت سیب ایرانی


شما این عبارت رو اینطوری بریز تو متغیر words


string[] words=("قیمت سیب ایرانی").Split(new string[]{" "}, StringSplitOptions.RemoveEmptyEntries);

دستور بالا یک آرایه از رشته درست میکنه و هرکلمه رو جدا میزاره تو یک واحد آرایه
داده هایی که باید جستجو توشون انجام بشه رو هم که خودتون گذاشتین تو لیست
بقیشم که دستوز Linq هست و شما چیزی نمیخواد تعریف کنید خودش کارارو انجام میده

dele_ghamgin_2008
یک شنبه 16 فروردین 1394, 00:55 صبح
شما یک یا چند کلمه داری که میخوای هر عبارتی که دارای یکی از اونها بود پیدا بشه
برای این کار مثلاً شما کلماتت طبق گفته خوذتون اینه

قیمت سیب ایرانی


شما این عبارت رو اینطوری بریز تو متغیر words


string[] words=("قیمت سیب ایرانی").Split(new string[]{" "}, StringSplitOptions.RemoveEmptyEntries);

دستور بالا یک آرایه از رشته درست میکنه و هرکلمه رو جدا میزاره تو یک واحد آرایه
داده هایی که باید جستجو توشون انجام بشه رو هم که خودتون گذاشتین تو لیست
بقیشم که دستوز Linq هست و شما چیزی نمیخواد تعریف کنید خودش کارارو انجام میده

اینجوری هم نوشتم باز کاری انجام نداد :
private void txtTag_TextChanged(object sender, EventArgs e) {
var search = LstAll.Items.Cast<string>().ToList();
string[] words = (txtTag.Text).Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
search.Where(src => words.All(word => src.Contains(word)));


}

am_al_59
یک شنبه 16 فروردین 1394, 01:05 صبح
این خطو

search.Where(src => words.All(word => src.Contains(word)));



تبدیل کن به


search.Where(src => words.َAny(word => src.Contains(word)));

dele_ghamgin_2008
یک شنبه 16 فروردین 1394, 01:11 صبح
این خطو

search.Where(src => words.All(word => src.Contains(word)));



تبدیل کن به


search.Where(src => words.َAny(word => src.Contains(word)));



به این شکل هم تبدیل کردم ولی باز هم هیچ اتفاقی نمی افته :

private void button1_Click(object sender, EventArgs e) {
var search = LstAll.Items.Cast<string>().ToList();
string[] words = ("قیمت سیب ایرانی").Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
search.Where(src => words.Any(word => src.Contains(word)));
}

am_al_59
یک شنبه 16 فروردین 1394, 01:13 صبح
اون لیستی که در search قرار داره رو Text بفرست خودم بنویسم
در حالت Debug میتونی همشو راحت کپی پیست کنی

dele_ghamgin_2008
یک شنبه 16 فروردین 1394, 01:24 صبح
اون لیستی که در search قرار داره رو Text بفرست خودم بنویسم
در حالت Debug میتونی همشو راحت کپی پیست کنی


قیمت بهترین سیب ایرانی
قیمت انواع سیب ایرانی
مرکز تولید سیب ایرانی
فروش سیب قرمز تازه
انواع سیب سبز ایرانی
تولید سیب قرمز اعلا
قیمت فروش سیب ایرانی
قیمت تولید سیب برای ایرانی ها

dele_ghamgin_2008
یک شنبه 16 فروردین 1394, 01:29 صبح
اومدم کد رو به این شکل تغییر دادم :

var search = LstAll.Items.Cast<string>().ToList();
string[] words = ("قیمت ایرانی").Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
var find = search.Where(src => words.Any(word => src.Contains(word))).ToArray();
lstOne.Items.AddRange(find);


لیست باکس من که گفتم آیتم هاش چیه . ولی خروجی کار به این شکل میشه :

قیمت بهترین سیب ایرانی
قیمت انواع سیب ایرانی
مرکز تولید سیب ایرانی
انواع سیب سبز ایرانی
قیمت فروش سیب ایرانی
قیمت تولید سیب برای ایرانی ها


این خروجی اشتباست زیرا ، این میاد سرچ میکنه بین کلماتی که ما بهش دادیم و دستور AND رو اجرا نمیکنه و به عبارتی شرط OR داره بررسی میشه . یعنی من بهش گفتم هر آیتمی که قیمت ایرانی توش هست رو بیاب ، در حالی که اون برای من انواع سیب سبز ایرانی رو هم پیدا کرده در حالی که این آیتم توش قیمت نداره ، درواقع برنامه اومده سرچ کرده هر آیتمی که توش قیمت داشت رو آورد ، بعد اومد هر آیتمی که توش ایرانی بود رو هم آورد ، نیومد هردو رو باهم بررسی کنه.

am_al_59
یک شنبه 16 فروردین 1394, 01:31 صبح
خدا منو مرگ بده اینکه درسته:عصبانی++:
شما خروجیرو اصلاً نگه نمیداری:گریه:
این خطو

search.Where(src => words.Any(word => src.Contains(word))).ToList();




تبدیل کن به

List<string> result = search.Where(src => words.Any(word => src.Contains(word))).ToList();


لیست result حاوی تمامی عباراتیه که یکی از کلمات رو دارن
الان برنامه نمونشم میفرستم

am_al_59
یک شنبه 16 فروردین 1394, 01:34 صبح
اینم برنامه نمونش
آیتم هارو از توی فایل Text خوندم
برنامه نویس با پشت کار یک پست اینجا میزنه یکی هم تو اینباکس من

am_al_59
یک شنبه 16 فروردین 1394, 01:38 صبح
شما که میگی می خوای اگر یکی از آیتم ها بود پیدا بشه
یعنی الان میخوای همه آیتم ها توش باشه تا پیدا بشه ؟

dele_ghamgin_2008
یک شنبه 16 فروردین 1394, 01:40 صبح
خدا منو مرگ بده اینکه درسته:عصبانی++:
شما خروجیرو اصلاً نگه نمیداری:گریه:
این خطو

search.Where(src => words.Any(word => src.Contains(word))).ToList();




تبدیل کن به

List<string> result = search.Where(src => words.Any(word => src.Contains(word))).ToList();


لیست result حاوی تمامی عباراتیه که یکی از کلمات رو دارن
الان برنامه نمونشم میفرستم

خب الان نمیخوام بیاد با تک تک چک کنه ، میخوام هر دو مقدار رو باهم چک کنه . در پست قبلی توضیح دادم. ضمنا الان این خروجیش کجا نمایش داده میشه ؟

dele_ghamgin_2008
یک شنبه 16 فروردین 1394, 01:42 صبح
شما که میگی می خوای اگر یکی از آیتم ها بود پیدا بشه
یعنی الان میخوای همه آیتم ها توش باشه تا پیدا بشه ؟

یک آیتم رو که من خودم کدش رو همون بالا اول نوشتم که بلدم ، میخوام با همه کلمات بررسی بشه . دقیقا نوشتم که آیتم اولیه من چیه و خروجی باید چیرو به من تحویل بده .

am_al_59
یک شنبه 16 فروردین 1394, 01:42 صبح
این کد

List<string> result = search.Where(src => words.Where(word => src.Contains(word)).Count()==words.Length).ToList( );

همه آیتم هایی که شامل همه کلمات هستن رو میریزه تو result

این کد


List<string> result = search.Where(src => words.Any(word => src.Contains(word))).ToList();

فقط عباراتی که دارای حداقل یک کلمه باشن رو میریزه تو result

dele_ghamgin_2008
یک شنبه 16 فروردین 1394, 02:00 صبح
این کد

List<string> result = search.Where(src => words.Where(word => src.Contains(word)).Count()==words.Length).ToList( );

همه آیتم هایی که شامل همه کلمات هستن رو میریزه تو result

این کد


List<string> result = search.Where(src => words.Any(word => src.Contains(word))).ToList();

فقط عباراتی که دارای حداقل یک کلمه باشن رو میریزه تو result

من برنامه خودم رو براتون می فرستم شما یه نگاهی بهش بندازید . من هرکاری میکنم نمیشه که نمیشه .

am_al_59
یک شنبه 16 فروردین 1394, 02:04 صبح
بفرمایین مشکل فقط به خاطر مقداردهی DataSource بود که نمایش نمیداد
الان درسته

dele_ghamgin_2008
یک شنبه 16 فروردین 1394, 02:05 صبح
مهندس کد رو به این شکل تغییر دادم به درستی عمل کرد :


lstOne.Items.Clear();
var search = LstAll.Items.Cast<string>().ToList();
string[] words = (txtTag.Text).Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
var find = search.Where(src => words.Where(word => src.Contains(word)).Count() == words.Length).ToArray();
lstOne.Items.AddRange(find);

am_al_59
یک شنبه 16 فروردین 1394, 02:10 صبح
کل مشکل شما مال همین addRange بود
توی همون برنامه ببین من مقدار DataSource رو برابر لیست قرار دادم

dele_ghamgin_2008
دوشنبه 17 فروردین 1394, 13:35 عصر
کل مشکل شما مال همین addRange بود
توی همون برنامه ببین من مقدار DataSource رو برابر لیست قرار دادم

فقط یک مشکل دیگه داره اونه که مثلا اگر آیتم های من این ها باشن :

سیب شفاف
کاربرد سیب شفافیت

و من توی سرچ عبارت شفا رو بنویسیم ، این دو آیتم برای من پیدا میشن درحالی که ایندو شفا رو ندارند بلکه شفاف و شفافیت رو دارند . نمیخوام ایندو رو پیدا کنه و فقط میخوام خود اون کلمه اگه وجود داشت رو پیدا کنه . آیا راهی هست ؟ ممنون میشم کمک کنید.

am_al_59
دوشنبه 17 فروردین 1394, 13:46 عصر
List<string> result = search.Where(src => words.Where(word => src.Contains(word+" ")||src.Contains(" "+word)).Count()==words.Length).ToList( );

dele_ghamgin_2008
دوشنبه 17 فروردین 1394, 14:04 عصر
List<string> result = search.Where(src => words.Where(word => src.Contains(word+" ")||src.Contains(" "+word)).Count()==words.Length).ToList( );



بازم همون قبلی هارو پیدا میکنه . و فقط شفا رو پیدا نمیکنه . شفاف رو هم پیدا میکنه

dele_ghamgin_2008
دوشنبه 17 فروردین 1394, 14:08 عصر
اینم برنامه ای که شما کد رو دادید گذاشتم ولی ج نداد.

am_al_59
دوشنبه 17 فروردین 1394, 14:09 عصر
اون کد دقیقاً کلمات را جستجو میکند و کد قبلیش عبارات وقتی شما زدی شفا و اونو رو پیدا نکنه مگه درست نیست

dele_ghamgin_2008
دوشنبه 17 فروردین 1394, 14:22 عصر
اون کد دقیقاً کلمات را جستجو میکند و کد قبلیش عبارات وقتی شما زدی شفا و اونو رو پیدا نکنه مگه درست نیست

آره نباید پیدا بکنه . ولی این کد شمارو که میزنم باز هم پیدا میکنه . نمونش رو فرستادم . اگه زحمتی نیست مجدد ببینید.

البته اون دستور || رو برداشتم و به این شکل نوشتم درست شد .

search.Where(src => words.Where(word => src.Contains(word + " ")).Count() == words.Length)

am_al_59
دوشنبه 17 فروردین 1394, 14:26 عصر
اینطوری بزن

List<string> result = search.Where(src => words.Where(word => src.Split(new string[]{" "},StringSplitOptions.RemoveEmptyEntries).Any(b=>b==word)).Count() == words.Length).ToList();

dele_ghamgin_2008
دوشنبه 17 فروردین 1394, 15:09 عصر
اینطوری بزن

List<string> result = search.Where(src => words.Where(word => src.Split(new string[]{" "},StringSplitOptions.RemoveEmptyEntries).Any(b=>b==word)).Count() == words.Length).ToList();



ممنونم . این جواب داد . یه دونه ای مهندس خیلی کمکم کردی . خدا خیرت بده.