-2
double find = 0;
            
 var listQ = new List<double>() {1, 3, 3.2, 4, 4.1 ,5};
            
 double i = 3.5;
            
find = listQ.Aggregate((x, y) => Math.Abs(x - i) < Math.Abs(y - i) ? x : y);
            
            
            
Print("item"+find);

// find will return 3.2, now i want to find the closest number from 3.2 and that would be 3 ...

Is there a method allowing me to do that automatically? So that the variable i always = find? The result from find must take the place of i. I want to send back the new result to i and relist all closests till listQ is exhausted.

Thank you

Mihai Alexandru-Ionut
  • 47,092
  • 13
  • 101
  • 128
Frankdot
  • 19
  • 6
  • 4
    It is not fully clear what you want. Do you *first* want to find the number in the list closest to 3.5 and *next* want to find the number in the list closest to that result? – JHBonarius Sep 23 '20 at 15:02
  • first find closest from 3.5, 3.2, than find closest from 3.2, if 3 is teh result than find closest from 3 ... once new closest is found i would equal new result. – Frankdot Sep 23 '20 at 15:05
  • By "closest", do you mean, the closest integer, or the closest in the list ? – MarleneHE Sep 23 '20 at 15:10
  • But 3.2 is the closest number in the list from 3.2.... do you want to remove 3.2 from the list? This is beginning to sound like a [x-y problem](http://xyproblem.info/). What do you *really* want to achieve?? – JHBonarius Sep 23 '20 at 15:28
  • the list is renewing constantly so i guess removing the number wont change a thing. – Frankdot Sep 23 '20 at 16:18

1 Answers1

0

I think i did understand you correctly, you request two numbers not one, basing the second one in the first result, but using the same list (without the found item); you can do the next:

public static void Main()
{
    double number1 = 0;
        
        var listQ = new List<double>() {1, 3, 3.2, 4, 4.1 ,5};

        double i = 3.5;

    number1 = listQ.FindClosest(i); //this is what you have
    //the where will exclude the number just found, and search based on that number.
    double number2 = listQ.Where(a=>a!=number1).FindClosest(number1);


    Console.WriteLine("item " +number1 + "Item 2: " + number2);
}

begin FindClosest an extension method:

public static class ListDoubleExtensions
{
    public static double FindClosest(this IEnumerable<double> listQ, double number)
    {
        return  listQ.Aggregate((x, y) => Math.Abs(x - number) < Math.Abs(y - number) ? x : y);
    }
}

UPDATE after OP's comment

It is not fully clear what you are looking for, but run it on a loop should do the job:

public static void Main()
{
        double number1 = 0;
    
    var listQ = new List<double>() {1, 3, 3.2, 4, 4.1 ,5};

    double i = 3.5;
    
    int loops = listQ.Count();
    double previousNumber = i;
    for(int iterator = 0; iterator<loops; iterator++){
            number1 = listQ.FindClosest(previousNumber); //this is what you have
        listQ = listQ.RemoveFromList(number1);
        Console.WriteLine("item " +number1);
        previousNumber = number1;

    }
}

then you need to add another extension method to remove the element from the list

public static class ListDoubleExtensions
{
    public static double FindClosest(this IEnumerable<double> listQ, double number)
    {
        return  listQ.Aggregate((x, y) => Math.Abs(x - number) < Math.Abs(y - number) ? x : y);
    }
    
    public static List<double> RemoveFromList(this List<double> listQ, double number)
    {
        return listQ.Where(a=>a!=number).ToList();
    }
}

fiddle: https://dotnetfiddle.net/

TiGreX
  • 1,602
  • 3
  • 26
  • 41
  • sounds about right... but it's a weird requirement.... – JHBonarius Sep 23 '20 at 15:29
  • TiGrex is close from what i am looking for. JH i try to create a simulation. Everytime i get the result of closest to i, i must find the next number in the list closer from find. In this solution i need everytime to create a new number 3, 4, 5 for any new result. This solution work but force me to create a new double number variable for every number in the list. Well in this case its a bad example because there is only 2 possibilities. – Frankdot Sep 23 '20 at 15:48
  • @Frankdot can you please have a look if it is what you want. still not very clear. – TiGreX Sep 23 '20 at 16:17
  • Thank you TiGrex, it needs a little bit modification but i will manage. – Frankdot Sep 23 '20 at 16:40
  • @Frankdot no aproved answer then? – TiGreX Sep 24 '20 at 12:41
  • what do i need to do to approve i am new here , sorry – Frankdot Sep 24 '20 at 14:37
  • @Frankdot haha no worries , I forgot you're new. Basically there is a green tick on each answer that you can give when the answer is the one that fix your issue . In top of that there is up and down button for every answer too. That's to be used when you are browsing then you find an answer that is useful to you, even if you're not the one who did the question . – TiGreX Sep 24 '20 at 14:45
  • ok its done i clicked the green checkmark, hope it gets you points – Frankdot Sep 24 '20 at 14:55
  • is it possible to reformat the script without classes? – Frankdot Oct 19 '20 at 14:45
  • @Frankdot I'm not sure what do you mean "without classes" this is another option, but not sure if it is this https://dotnetfiddle.net/7oAlhO ; in C#9 you can leave just the two methods, remove the "main" method header and it will work https://stackoverflow.com/questions/62969728/c-sharp-9-0-support-for-top-level-programs-in-visual-studio-2019 – TiGreX Oct 19 '20 at 15:04
  • I am trying to apply differently your solution to my algorithm. It is script in Ninjatrader.com. I can introduce it in the script but it wont return nothing in the output window. Ill have to ask them (NT) what is wrong. I just rethink my algorithm and i want to do the same but without ListQ. Imagine double i = 3.5 and after been process in the algo double Y = 4. How could i return 4 in the i = 4 and than collect the new value Y = 7 for example. Than it becomes i = 7 ... and Y return a new value that we store in Qlist. QList {3.5, 4, 7 ...}? – Frankdot Oct 19 '20 at 15:34