-1

I have two objects. I want to sort first object's QuickLinks property according to second object's QuickLinks. It should be based on QuickLinkContent.ConfigId

NavigationMenuContent nmc1 = new NavigationMenuContent();
NavigationMenuContent nmc2 = new NavigationMenuContent();

public class NavigationMenuContent
    {
        public int LanguageID { get; set; }

        public QuickLinkContent[] QuickLinks { get; set; }
    }

public class QuickLinkContent
    {
        public Guid ConfigID { get; set; }

        public string Name { get; set; }

        public string Description { get; set; }

        public string Url { get; set; }

        public Guid? ServiceProviderID { get; set; }

        public SchemeContentFile Document { get; set; }
    }

I tried doing it like this:

nmc1.QuickLinks = nmc1.QuickLinks.OrderBy(q => nmc2.QuickLinks.ToList().IndexOf(q.ConfigID));

but getting error :

Cannot convert from System.Guid to QuickLnkContent.

NetMage
  • 26,163
  • 3
  • 34
  • 55
Prashant Yadav
  • 531
  • 2
  • 9
  • 25

3 Answers3

3

I would use a dictionary to do this.

Dictionary<Guid, int> map =
    nmc2
        .QuickLinks
        .Select((x, n) => (x, n))
        .ToDictionary(z => z.x.ConfigID, z => z.n);

nmc1.QuickLinks =
    nmc1
        .QuickLinks
        .OrderBy(x => map[x.ConfigID])
        .ToArray();
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
1

Create array of ordered config ids:

var orderedIds = nmc2.QuickLinks.Select(ql => ql.ConfigID).ToArray();

And then use it to order links

nmc1.QuickLinks = nmc1.QuickLinks
   .OrderBy(ql => Array.IndexOf(orderedIds, ql.ConfigID))
   .ToArray();
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • O(n2) operation. The other solution will usually be faster – Charlieface Jan 13 '21 at 21:20
  • @Charlieface first of all it's premature optimization. You don't want to create dictionaries to sort an array of 5 items. And other solution will fail 1) when nmc1 has unique items, 2) when nmc2 has duplicates. So you (maybe) saved few ticks of cpu, but got more code to maintain and two problems to deal with – Sergey Berezovskiy Jan 13 '21 at 22:06
1

Using an array extension method, you can solve this generally:

public static int IndexOfBy<T, TKey>(this T[] a, TKey target, Func<T,TKey> keyFn, EqualityComparer<TKey> cmp = null) {
    cmp = cmp ?? EqualityComparer<TKey>.Default;
    for (int j1 = 0; j1 < a.Length; ++j1) {
        if (cmp.Equals(keyFn(a[j1]), target))
            return j1;
    }
    return -1;
}

With the extension method available, you can use OrderBy:

nmc1.QuickLinks = nmc2.QuickLinks.OrderBy(q => nmc2.QuickLinks.IndexOfBy(q.ConfigID, q2 => q2.ConfigID)).ToArray();
NetMage
  • 26,163
  • 3
  • 34
  • 55