0

I need to Sort a List using another List. I am trying to use :

var docsIds = new List<int>() { 1, 7, 4 };
var tileSizes = new List<int>();
tileSizes = tileSizes.OrderBy(x => docsIds.IndexOf());

Input : 1,2,3,4,5,6,7

Expected Output: 1,7,4,2,3,5,6

Any help is appreciated.

Jose Francis
  • 950
  • 13
  • 28
  • 3
    Test input and expected output would be of help – Camilo Terevinto Jul 06 '17 at 21:55
  • https://stackoverflow.com/questions/3945935/sort-one-list-by-another, https://stackoverflow.com/questions/15275269/sort-a-list-from-another-list-ids, https://stackoverflow.com/questions/3470098/list-sort-based-on-another-list, https://stackoverflow.com/questions/14227757/sort-one-list-based-on-another – CodeCaster Jul 06 '17 at 21:57
  • @CodeCaster I cannot use this : docs = docs.OrderBy(d => docsIds.IndexOf(d.Id)).ToList(); as I don't have an Id inside the docs. – Jose Francis Jul 06 '17 at 22:00
  • @JoseFrancis the input does not make it clear whether it's for the doccsIds or for tileSizes – Camilo Terevinto Jul 06 '17 at 22:01
  • Read [ask] and create a [mcve]. It's unclear what exactly you want to achieve. – CodeCaster Jul 06 '17 at 22:02
  • @CamiloTerevinto tileSizes will have 4,1,7 as a list of int and I need to sort it in order of docsIds. – Jose Francis Jul 06 '17 at 22:03
  • @JoseFrancis why not just return docsIds then? It's not clear what you are trying to do – Camilo Terevinto Jul 06 '17 at 22:04
  • @CodeCaster edited the question. – Jose Francis Jul 06 '17 at 22:06
  • If `tileSizes` will have `{ 4, 1, 7 }` then why don't you show that in your example? And show the actual output, not just the expected output. Or at least describe how it's not working. Below your code, you state that the Input is `1, 2, 3, 4, 5, 6, 7`. What does `IndexOf` return if a value is not found in the lookup list? How does that affect your ordering? – Rufus L Jul 06 '17 at 22:09

3 Answers3

3

Assuming that tileSizes only has values chosen from docIds (which seems to be the intent, though the question is a bit unclear), then the missing piece is a parameter to IndexOf(), specifically IndexOf(x).

Then, IndexOf() returns an integer showing where in docIds the value would be, and OrderBy() can use that in sorting.

Oh, right. And OrderBy() doesn't return a List, but rather an Enumerable, so you'll need a ToList() at the end. Putting that all together, your last line should be something like...

tileSizes = tileSizes.OrderBy(x => docsIds.IndexOf(x)).ToList();
Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
John C
  • 1,931
  • 1
  • 22
  • 34
0

I usually like to do things a bit more manually, so there is my solution:

List<int> randomItems = new List<int>(){1,2,3,4,5,6,7};
List<int> outputOrder = new List<int>(){0,6,3,1,2,4,5};
List<int> resultList = new List<int>();

foreach(int order in outputOrder)
{
    resultList.Add(randomItems[order]);
}

Edited in order to replicate the OP values

The resultList will contain: 1,7,4,2,3,5,6

Alternatively you can have the outputOrder like this:

List<int> outputOrder = new List<int>(){1,7,4,2,3,5,6};

and simply change the loop instruction to:

resultList.Add(randomItems[order--]);

And the result will be the same.

DGaspar
  • 628
  • 1
  • 6
  • 14
  • I know it's not the most efficient solution, but at least you can put a breakpoint and see what is happening and have control over it. – DGaspar Jul 06 '17 at 22:12
  • 1
    I think the OP wants the result list to be sorted based on the outputOrder list, which means it should be `{1, 2, 14, 95, 45}` – Rufus L Jul 06 '17 at 22:12
  • What if the lists don't have the same amount of values? – Camilo Terevinto Jul 06 '17 at 22:13
  • @Camilo Terevinto you can always and code (an "if") to prevent that situation and do whatever you want in that situation. IE some throw or error handling – DGaspar Jul 06 '17 at 22:16
  • 1
    This seems to be an answer to a different question that what the OP asked. – Klitos Kyriacou Jul 06 '17 at 22:17
  • The `outputOrder` is not a list of indexes. It is a list of numbers that defines the hierarchy of those numbers. E.g. for an `outputOrder` of {1, 7, 4}, you must sort the list such that all 1's come before all 7's and all 7's come before all 4's and all 4's come before any number not in the list. This is not what you've answered here. – Klitos Kyriacou Jul 06 '17 at 22:26
0

If tileSizes are distinct and always contain all docsIds, Union can be used for an O(n) complexity:

tileSizes = docsIds.Union(tileSizes).ToList();        // { 1, 7, 4, 2, 3, 5, 6 }
Slai
  • 22,144
  • 5
  • 45
  • 53