简体   繁体   中英

C# iterate List for specific values then Add them to another List in a certain order

Each instance of some Lists in my program are in an arbitrarily different order (as a result of an unfixed bug in Umbraco CMS Forms), and I need to rearrange them to the correct order. I can't use indices and OrderBy as each time the order is different.

I have been trying to iterate the existing List, then, when it finds the correct String that should be in position [0], using .Add to add it to another, empty List. Then continue through adding each value to the correct index.

I can't figure out a way to do this. I need the logic to basically say "look in this list, if the string equals this value, add it to this other list at position 0, then look for the next string to add at position 1, and so on", so at the end I will have the new List in the correct order.

// List to populate from record in wrong order
var extractedFields = new List<KeyValuePair<string, string>>();
// new list to copy values across in correct order
var newOrderFields = new List<KeyValuePair<string, string>>();
// separate list containing data field captions, used to iterate later
var extractedCaptions = new List<string>();
foreach (var field in record.RecordFields)
{
    var extractValue = field.Value.ValuesAsString().NullSafeToString();
    var extractType = CGHelper.CleanString(field.Value.Field.FieldType.Name).ToLower();
    var extractCaption = field.Value.Field.Caption;
    extractedFields.Add(new KeyValuePair<string, string>(extractType, 
    extractValue));
    extractedCaptions.Add(extractCaption);
}

var count = 0;

foreach (var cap in extractedCaptions.ToList())
{
    if (cap == "Opportunity ID")
    {
        extractedCaptions.Remove(cap);
        extractedCaptions.Insert(0, cap);
        var key = extractedFields[count].Key;
        var value = extractedFields[count].Value;
        newOrderFields.Add(new KeyValuePair<string, string>(key, value));
    }
    else if (cap == "Name")
    {
    // etc. identify string to be put into correct order

So to try and explain further, a user submits a form with the fields in a certain order. When we load that form and pull the record through (from the Umbraco Form), it is in a totally different and arbitrary order (and is in a different order for every single form).Therefore I need to iterate the fields and put them back into the order they were in the original form...

I don't know if I understand the situation correctly. But you can utilize the IComparer<T> interface for custom sorting logic.

using System;
using System.Collections.Generic;

namespace Comparer
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            var list = new[]{"Foobar", "Baz", "Foo", "Foobar", "Bar", };
            Array.Sort(list, new CustomComparer(new[]{"Foo", "Bar", "Baz", "Foobar"}));
            list.Dump();
            // will dump : Foo,Bar,Baz,Foobar,Foobar
        }
    }

    public class CustomComparer : IComparer<string>
    {
        private readonly string[] priorityList;

        public CustomComparer(string[] priorityList)
        {
            this.priorityList = priorityList;
        }

        public int Compare(string x, string y)
        {
            var xIx = Array.IndexOf(priorityList, x);
            var yIx = Array.IndexOf(priorityList, y);
            return xIx.CompareTo(yIx);
        }
    }
}

This will sort the array according to indexes proved in the constructor.

Fiddle

I wrote a small example. You can see it working here .

The idea is iterating the ordered list and search to every value in other one.

Code:

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main()
    {
        List<string> ordered = new List<string>(){ "a", "b", "c", "d"};
        List<string> nonOrderedAndMissing = new List<string>(){ "c", "d", "a"};
        
        // here is the join
        var newList = ordered.Select(a => nonOrderedAndMissing.Contains(a) ? a : null).Where(d => d != null).ToList();
        
        // checking here
        foreach(var a in newList){
            Console.WriteLine(a);   
        }
        
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM