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

namespace LabelerCore.Model.Math
{
    public static class Utils
    {
        //non ordered
        public static IEnumerable<T> Select<T>(IEnumerable<T> arr, IEnumerable<int> indices)
        {
            return arr.Select((v, i) => new KeyValuePair<T, int>(v, i))
                      .Where(x => indices.Contains(x.Value))
                      .Select(x => x.Key).ToArray();
        }

        public static T[] Select<T>(T[] arr, int[] indices)
        {
            return arr.Select((v, i) => new KeyValuePair<T, int>(v, i))
                      .Where(x => indices.Contains(x.Value))
                      .Select(x => x.Key).ToArray();
        }

        public static IEnumerable<T> Select<T>(IEnumerable<T> arr, IEnumerable<bool> f)
        {
            return arr.Select((v, i) => new KeyValuePair<T, int>(v, i))
                      .Where(x => f.ElementAt(x.Value))
                      .Select(x => x.Key).ToArray();
        }


        public static int[] Concat(int[] x, int[] y)
        {
            int[] z = new int[x.Length + y.Length];
            x.CopyTo(z, 0);
            y.CopyTo(z, x.Length);
            return z;
        }

        //ordered select, return arr[indices]
        public static T[] ReOrder<T>(T[] arr, int[] indices)
        {
            T[] ret = new T[indices.Length];
            int it = 0;
            foreach(int idx in indices)
                ret[it++] = arr[idx];
            return ret;
        }

        public static double CheckBoundaries(double val, double lower, double upper)
        {
            double ret = val < lower ? lower : val;
            ret = ret > upper ? upper : ret;
            return ret;
        }



    }
}                                                      