Taqqoslash bo'yicha ikkita mag'lubiyat qatorini birlashtirishga urinish

Quyida mening sinfim:

public class Regions
    {
        public int Id { get; set; }
        public string[] ParentName { get; set; }
    }

Hozirda men yuqorida keltirilgan hududlar sinfining ikkita ro'yxatini topdim:

var region1 = new Regions();
var region2 = new Regions();

Endi ParentName quyidagi region1 uchun ma'lumotlarni o'z ichiga oladi:

[0] : Abc.mp3,Pqr.mp3
[1] : Xxx.mp3
[2] : kkk.mp3
[3] : ppp.mp3,zzz.mp3,rrr.mp3,ddd.mp3

Endi ParentName region2 uchun quyida keltirilgan ma'lumotlarni o'z ichiga oladi:

[0] : Abc.mp3,Pqr.mp3,lmn.mp3
[1] : rrr.mp3,ggg.mp3,yyy.mp3

Endi mintaqaning ParentName2 ni region1 ga birlashtirishga harakat qilaman, agar region1ning biron bir qismi region2 bilan o'xshash bo'lsa, qaydlarni vergul bilan ajratib bo'lgandan keyin quyidagi kabi:

[0] : Abc.mp3,Pqr.mp3,lmn.mp3
[1] : Xxx.mp3
[2] : kkk.mp3
[3] : ppp.mp3,zzz.mp3,rrr.mp3,ddd.mp3,ggg.mp3,yyy.mp3

Endi yuqorida kutilgan natijalar bo'yicha Abc.mp3 va Pqr.Mp3 (Region1 va Region2) faqat Lmn.mp3 mos kelmaydi, shuning uchun u mintaqaning oxirida qo'shiladi .

<1> va region2 dan eng so'nggi qaydlar uchun rrr.mp3 (bir tanlov kifoya qiladi), shuning uchun region2dan ya'ni ggg.mp3, yyy.mp3 mintaqadan oxirigacha qo'shilmaydi1 .

Chiqish 1 Mintaqada bo'laman:

[0] : Abc.mp3,Pqr.mp3
[1] : Xxx.mp3
[2] : kkk.mp3
[3] : ppp.mp3,zzz.mp3,rrr.mp3,ddd.mp3
[4] : Abc.mp3,Pqr.mp3,lmn.mp3
[3] : rrr.mp3,ggg.mp3,yyy.mp3

Kod:

region1.ParentName = region1.ParentName.Concat(region2.ParentName).Distinct().ToArray();


public static T[] Concat(this T[] x, T[] y)
        {
            if (x == null) throw new ArgumentNullException("x");
            if (y == null) throw new ArgumentNullException("y");
            int oldLen = x.Length;
            Array.Resize(ref x, x.Length + y.Length);
            Array.Copy(y, 0, x, oldLen, y.Length);
            return x;
        }
3
@jdweng: Kechirasiz, lekin bu ishga qo'shilish menga yordam berishi mumkin deb o'ylayman
qo'shib qo'ydi muallif Learning-Overthinker-Confused, manba
@RomaDoskoch Qanday rrr.mp3, ggg.mp3, yyy.mp3 xxx.mp3 bilan birga xxx.mp3 viloyatda emas. Men xohlagan joy1 region1 va region2dan mos kelmasligi kerak. Faqatgina region1 va region2 yozuvlari birlashtirilishi kerak
qo'shib qo'ydi muallif Learning-Overthinker-Confused, manba
@RomaDoskoch: Ha, hatto region1 va region2 dan mos keladigan magistralning bir qismi vergul bilan ajratilgandan so'ng birlashtirilishi kerak .Keyingi oxirida regionda parentname alohida yozuvlarni o'z ichiga olishi kerak.
qo'shib qo'ydi muallif Learning-Overthinker-Confused, manba
@RomaDoskoch: Ha, hatto region1 va region2 dan mos keladigan magistralning bir qismi vergul bilan ajratilgandan so'ng birlashtirilishi kerak .Keyingi oxirida regionda parentname alohida yozuvlarni o'z ichiga olishi kerak.
qo'shib qo'ydi muallif Learning-Overthinker-Confused, manba
@jdweng: Bu faqat ro'yxat yoki array.So faqat bir lavozim
qo'shib qo'ydi muallif Learning-Overthinker-Confused, manba
qo'shib qo'ydi muallif jdweng, manba
Kvadrat qavsdagi raqamlar nimani anglatadi?
qo'shib qo'ydi muallif jdweng, manba
Kvadrat qavsdagi raqamlar nimani anglatadi?
qo'shib qo'ydi muallif jdweng, manba
Keyin sizda var region1 = yangi ro'yxat > ();
qo'shib qo'ydi muallif jdweng, manba
Keyin sizda var region1 = yangi ro'yxat > ();
qo'shib qo'ydi muallif jdweng, manba
@Eshitish, siz kutgan natijalar to'g'ri ekanligiga ishonchingiz komilmi? ikkinchi satr bo'lmasligi kerak: "Xxx.mp3, rrr.mp3, ggg.mp3, yyy.mp3" ?
qo'shib qo'ydi muallif Roman Doskoch, manba
@Learning, shuning uchun siz regionlarni region2dan region1ga birlashtirmoqchi bo'lsangiz, har ikki mintaqadagi qadriyatlar bilan farq qilish kerakmi?
qo'shib qo'ydi muallif Roman Doskoch, manba
@Learning, shuning uchun siz regionlarni region2dan region1ga birlashtirmoqchi bo'lsangiz, har ikki mintaqadagi qadriyatlar bilan farq qilish kerakmi?
qo'shib qo'ydi muallif Roman Doskoch, manba

6 javoblar

Nomlaringizning dublikatlar va ularning qanday ishlashi kerakligi noma'lum, ammo mana bu kirishlar bilan istalgan natijani ishlab chiqaradigan LINQ usuli mavjud:

var e2Sets = region2.ParentName.Select(e2 => e2.Split(',')).ToList();
var result =
    from e1 in region1.ParentName
    let e1Set = e1.Split(',')
    let e2AppendSet = (
       from e2Set in e2Sets
       where e1Set.Intersect(e2Set).Any()
       from e2New in e2Set.Except(e1Set)
       select e2New
    ).Distinct()
    select string.Join(",", e1Set.Concat(e2AppendSet));

result.ToArray() will give you the desired new region1.ParentName.

Qanday ishlaydi:

Ikki kirish suhbatining Cartesian mahsulotiga asosan kerak bo'lganligimiz sababli, ichki ko'chadan bir necha string.Split ni oldini olish uchun ikkinchi qatordagi bo'linadigan satrlardagi qatorlarni tayyorlashni boshlaymiz.

Birinchi ketma-ketlikning har bir elementi uchun biz uni satrlarga o'tkazamiz, ikkita ketma-ketlikdagi ikkita ketma-ketlik uchun ( Intersect metodini) Faqat usulidan foydalaning. So'ngra barcha mos bo'lmagan satrlarni tekis qilamiz, Turli , potentsial nusxalarini olib tashlash, ikkita to'plamni birlashtirib, yangi vergul bilan ajratilgan mag'lubiyatni yaratish uchun string.Join dan foydalaning.

1
qo'shib qo'ydi

Nomlaringizning dublikatlar va ularning qanday ishlashi kerakligi noma'lum, ammo mana bu kirishlar bilan istalgan natijani ishlab chiqaradigan LINQ usuli mavjud:

var e2Sets = region2.ParentName.Select(e2 => e2.Split(',')).ToList();
var result =
    from e1 in region1.ParentName
    let e1Set = e1.Split(',')
    let e2AppendSet = (
       from e2Set in e2Sets
       where e1Set.Intersect(e2Set).Any()
       from e2New in e2Set.Except(e1Set)
       select e2New
    ).Distinct()
    select string.Join(",", e1Set.Concat(e2AppendSet));

result.ToArray() will give you the desired new region1.ParentName.

Qanday ishlaydi:

Ikki kirish suhbatining Cartesian mahsulotiga asosan kerak bo'lganligimiz sababli, ichki ko'chadan bir necha string.Split ni oldini olish uchun ikkinchi qatordagi bo'linadigan satrlardagi qatorlarni tayyorlashni boshlaymiz.

Birinchi ketma-ketlikning har bir elementi uchun biz uni satrlarga o'tkazamiz, ikkita ketma-ketlikdagi ikkita ketma-ketlik uchun ( Intersect metodini) Faqat usulidan foydalaning. So'ngra barcha mos bo'lmagan satrlarni tekis qilamiz, Turli , potentsial nusxalarini olib tashlash, ikkita to'plamni birlashtirib, yangi vergul bilan ajratilgan mag'lubiyatni yaratish uchun string.Join dan foydalaning.

1
qo'shib qo'ydi

Jarayon qismlarini olish va mos keladigan kodni topish uchun Join() usulini topish uchun Split() usulidan foydalanishingiz mumkin:

private static void Merge(Regions region, Regions region2)
{
    List> splittedLists = region.ParentName.Select(p => p.Split(new char[] { ',' }, StringSplitOptions.None).ToList()).ToList();
    List> splittedLists2 = region2.ParentName.Select(p => p.Split(new char[] { ',' }, StringSplitOptions.None).ToList()).ToList();
    List res = new List();

    foreach (var item in splittedLists)
    {
        bool wasMatch = false;           
        foreach (var s in item)
        {
            bool contains = false;
            foreach (var s2 in splittedLists2.Where(s2 => s2.Contains(s)))
            {
                wasMatch = true;
                contains = true;
                res.Add(string.Join(",", item.Concat(s2).Distinct()));
            }    
            if (contains)
            {
                contains = false;
                break;
            }
        }    
        if (!wasMatch)
        {
            res.Add(string.Join(",", item));
        }
    }    
    region.ParentName = res.ToArray();
}
1
qo'shib qo'ydi

Jarayon qismlarini olish va mos keladigan kodni topish uchun Join() usulini topish uchun Split() usulidan foydalanishingiz mumkin:

private static void Merge(Regions region, Regions region2)
{
    List> splittedLists = region.ParentName.Select(p => p.Split(new char[] { ',' }, StringSplitOptions.None).ToList()).ToList();
    List> splittedLists2 = region2.ParentName.Select(p => p.Split(new char[] { ',' }, StringSplitOptions.None).ToList()).ToList();
    List res = new List();

    foreach (var item in splittedLists)
    {
        bool wasMatch = false;           
        foreach (var s in item)
        {
            bool contains = false;
            foreach (var s2 in splittedLists2.Where(s2 => s2.Contains(s)))
            {
                wasMatch = true;
                contains = true;
                res.Add(string.Join(",", item.Concat(s2).Distinct()));
            }    
            if (contains)
            {
                contains = false;
                break;
            }
        }    
        if (!wasMatch)
        {
            res.Add(string.Join(",", item));
        }
    }    
    region.ParentName = res.ToArray();
}
1
qo'shib qo'ydi

Quyidagilarni qilishingiz mumkin:

public static void Merge(Regions first, Regions second)
{
    if (ReferenceEquals(first, null))
        throw new ArgumentNullException(nameof(first));

    if (ReferenceEquals(second, null))
        throw new ArgumentNullException(nameof(second));

    first.ParentName = first.ParentName.Merge(second.ParentName).ToArray();
}

private static IEnumerable Merge(this IEnumerable first, IEnumerable second)
{
    if (ReferenceEquals(first, null))
        throw new ArgumentNullException(nameof(first));

    if (ReferenceEquals(second, null))
        throw new ArgumentNullException(nameof(second));

    foreach (var f in first)
    {
        yield return f.Merge(second, ',');
    }
}

private static string Merge(this string first, IEnumerable second, char separator)
{
    Debug.Assert(first != null);
    Debug.Assert(second != null);

    var firstSplitted = first.Split(separator);

    foreach (var s in second)
    {
        var sSplitted = s.Split(separator);

        if (firstSplitted.Intersect(sSplitted).Any())
            return string.Join(separator.ToString(), firstSplitted.Union(sSplitted));
    }

    return first;
}

Bu topilgan birinchi o'yinda birlashishi mumkinligini unutmang; agar ikki nusxadagi qiymatlar mavjud bo'lsa, u o'yinni birinchi marotaba duch kelganida birlashtiradi.

Bu erda maxfiylik bo'linadi va g'alaba qozonadi. Muayyan mantiqni amalga oshirishda muammolarga duch kelsangiz, uni oddiy bosqichlarga o'tkazing va har bir chaqaloqning qadamini bajaring. Ishlay boshlaganingizdan so'ng, agar haqiqatan ham kerak bo'lsa, kodni yaxshilashingiz mumkin yoki uni yanada ixcham yoki ijrochi qilishingiz mumkin.

Agar shunday qilsangiz:

var first = new Regions();
var second = new Regions();
first.ParentName = new[] { "Abc.mp3,Pqr.mp3", "Xxx.mp3", "kkk.mp3", "ppp.mp3,zzz.mp3,rrr.mp3,ddd.mp3" };
second.ParentName = new[] { "Abc.mp3,Pqr.mp3,lmn.mp3", "rrr.mp3,ggg.mp3,yyy.mp3" };
Merge(first, second);

Kutilgan natijani olasiz. first.ParentName quyidagicha bo'ladi:

[0]: "Abc.mp3,Pqr.mp3,lmn.mp3"
[1]: "Xxx.mp3"
[2]: "kkk.mp3"
[3]: "ppp.mp3,zzz.mp3,rrr.mp3,ddd.mp3,ggg.mp3,yyy.mp3"
1
qo'shib qo'ydi
Aslida men shunday bir narsa deb o'ylagan edim: 2-qatordan vergilarni vergul bilan ajratgandan keyin solishtiring va mag'lubiyatning biron bir qismi yuqoridagi ro'yxatga olinadi. Masalan: Agar birinchi qayd haqida gapiradigan bo'lsam, Abc.mp3 - undan keyin region2dan viloyatga yozib olish mumkin. Bu kabi ish. Faqat bitta fikr
qo'shib qo'ydi muallif Learning-Overthinker-Confused, manba

Quyidagilarni qilishingiz mumkin:

public static void Merge(Regions first, Regions second)
{
    if (ReferenceEquals(first, null))
        throw new ArgumentNullException(nameof(first));

    if (ReferenceEquals(second, null))
        throw new ArgumentNullException(nameof(second));

    first.ParentName = first.ParentName.Merge(second.ParentName).ToArray();
}

private static IEnumerable Merge(this IEnumerable first, IEnumerable second)
{
    if (ReferenceEquals(first, null))
        throw new ArgumentNullException(nameof(first));

    if (ReferenceEquals(second, null))
        throw new ArgumentNullException(nameof(second));

    foreach (var f in first)
    {
        yield return f.Merge(second, ',');
    }
}

private static string Merge(this string first, IEnumerable second, char separator)
{
    Debug.Assert(first != null);
    Debug.Assert(second != null);

    var firstSplitted = first.Split(separator);

    foreach (var s in second)
    {
        var sSplitted = s.Split(separator);

        if (firstSplitted.Intersect(sSplitted).Any())
            return string.Join(separator.ToString(), firstSplitted.Union(sSplitted));
    }

    return first;
}

Bu topilgan birinchi o'yinda birlashishi mumkinligini unutmang; agar ikki nusxadagi qiymatlar mavjud bo'lsa, u o'yinni birinchi marotaba duch kelganida birlashtiradi.

Bu erda maxfiylik bo'linadi va g'alaba qozonadi. Muayyan mantiqni amalga oshirishda muammolarga duch kelsangiz, uni oddiy bosqichlarga o'tkazing va har bir chaqaloqning qadamini bajaring. Ishlay boshlaganingizdan so'ng, agar haqiqatan ham kerak bo'lsa, kodni yaxshilashingiz mumkin yoki uni yanada ixcham yoki ijrochi qilishingiz mumkin.

Agar shunday qilsangiz:

var first = new Regions();
var second = new Regions();
first.ParentName = new[] { "Abc.mp3,Pqr.mp3", "Xxx.mp3", "kkk.mp3", "ppp.mp3,zzz.mp3,rrr.mp3,ddd.mp3" };
second.ParentName = new[] { "Abc.mp3,Pqr.mp3,lmn.mp3", "rrr.mp3,ggg.mp3,yyy.mp3" };
Merge(first, second);

Kutilgan natijani olasiz. first.ParentName quyidagicha bo'ladi:

[0]: "Abc.mp3,Pqr.mp3,lmn.mp3"
[1]: "Xxx.mp3"
[2]: "kkk.mp3"
[3]: "ppp.mp3,zzz.mp3,rrr.mp3,ddd.mp3,ggg.mp3,yyy.mp3"
1
qo'shib qo'ydi
Aslida men shunday bir narsa deb o'ylagan edim: 2-qatordan vergilarni vergul bilan ajratgandan keyin solishtiring va mag'lubiyatning biron bir qismi yuqoridagi ro'yxatga olinadi. Masalan: Agar birinchi qayd haqida gapiradigan bo'lsam, Abc.mp3 - undan keyin region2dan viloyatga yozib olish mumkin. Bu kabi ish. Faqat bitta fikr
qo'shib qo'ydi muallif Learning-Overthinker-Confused, manba