-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.

10
  • 1
    You say you want to sort nmc1 list, but you are trying to sort QuickLinks array. So what you are actually trying to sort? Commented Jan 13, 2021 at 20:39
  • I want to sort nmc1.QuickLinks according to nmc2.QuickLinks Commented Jan 13, 2021 at 20:40
  • 2
    What does that even mean? For example, if I said "I want to sort this Person[] according to FirstName alphabetical descending" - that makes sense.. but "I want to sort this Person[] according to that Person[]" - it's not a specification of anything Commented Jan 13, 2021 at 20:40
  • nmc1 is a list. it doesn't have property QuickLinks Commented Jan 13, 2021 at 20:43
  • @SergeyBerezovskiy sorry for confustion, I've updated the question Commented Jan 13, 2021 at 20:46

3 Answers 3

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();
Sign up to request clarification or add additional context in comments.

1 Comment

This is the faster method usually
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();

2 Comments

O(n2) operation. The other solution will usually be faster
@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
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();

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.