
export class ArrayUtils {

    public static Equals(array1: Array<any>, array2: Array<any>): boolean {
        // if the other array is a falsy value, return
        if (!array2)
            return false;

        // compare lengths - can save a lot of time 
        if (array1.length != array2.length)
            return false;

        for (var i = 0, l = array1.length; i < l; i++) {
            // Check if we have nested arrays
            if (array1[i] instanceof Array && array2[i] instanceof Array) {
                // recurse into the nested arrays
                if (!ArrayUtils.Equals(array1[i], array2[i]))
                    return false;
            }
            else if (array1[i] != array2[i]) {
                // Warning - two different object instances will never be equal: {x:20} != {x:20}
                return false;
            }
        }
        return true;
    }

    // public static ToDropDownOptions(array: any[], keyProperty: string | number, valueProperty: string | number): DropDownOption[] {
    //     var result = [];
    //     for (let i = 0; i < array.length; i++) {
    //         const element = array[i];
    //         result.push(new DropDownOption(element[keyProperty], element[valueProperty]));
    //     }
    //     return result;
    // }


    public static GroupBy<T = any>(arr: Array<T>, groupKeyPrepareFunction: (obj: T) => any | any[]) {

        let groups = arr.reduce(function (groupModel, obj) {

            let keys = groupKeyPrepareFunction(obj);

            const addToGroup = (key: any, obj: T) => {
                let group = groupModel.find(g => g.key == key);
                if (group == null) {
                    group = new GroupModel(key);
                    groupModel.push(group);
                }
                group.values.push(obj);
            }

            if (Array.isArray(keys)) {
                for (let i = 0; i < keys.length; i++) {
                    const key = keys[i];
                    addToGroup(key, obj);
                }
            } else {
                addToGroup(keys, obj);
            }
            return groupModel;
        }, [] as GroupModel<T>[]);
        return groups;
    }
    public static RemoveDuplicate<T>(objArray: T[], duplicateDetection: (a: T, b: T) => boolean) {
        return objArray.filter((value, index, self) =>
            index === self.findIndex((t) => duplicateDetection(t, value))
        );
    }

    public static insertAt = (arr: any[], index: number, newItems: any) => [
        // part of the array before the specified index
        ...arr.slice(0, index),
        // inserted items
        newItems,
        // part of the array after the specified index
        ...arr.slice(index)
    ];

}

export class GroupModel<T = any> {
    constructor(key: any) {
        this.key = key;
        this.values = [];
    }

    key: any;
    values: T[];
}