All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.dermetfan.utils.ArrayUtils Maven / Gradle / Ivy

There is a newer version: 0.13.4
Show newest version
/** Copyright 2014 Robin Stumm ([email protected], http://dermetfan.net)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License. */

package net.dermetfan.utils;

import net.dermetfan.utils.math.Noise;

/** array utility methods
 *  @author dermetfan */
public abstract class ArrayUtils {

	/** @param array the array from which to access a value at the wrapped index
	 *  @return the value at the wrapped index
	 *  @see #wrapIndex(int, int) */
	public static  T wrapIndex(int index, T[] array) {
		return array[wrapIndex(index, array.length)];
	}

	/** @see #wrapIndex(int, Object[]) */
	public static int wrapIndex(int index, int[] array) {
		return array[wrapIndex(index, array.length)];
	}

	/** @see #wrapIndex(int, Object[]) */
	public static float wrapIndex(int index, float[] array) {
		return array[wrapIndex(index, array.length)];
	}

	/** Wraps the given index around the given length (of an array). For example for a length of 10:
* * * * * * * * *
indexreturns
00
55
100
155
200
555
* @param index the desired index * @param length the length of the array * @return the index wrapped around the array length */ public static int wrapIndex(int index, int length) { return (index + length) % length; } /** @param array the array that may contain the given value * @param value the value to search for in the given array * @param identity if {@code ==} comparison should be used instead of {@link Object#equals(Object) .equals()} * @return if the given value is contained in the given array */ public static boolean contains(T[] array, T value, boolean identity) { int i = array.length - 1; if(identity) { while(i >= 0) if(array[i--] == value) return true; } else while(i >= 0) if(array[i--].equals(value)) return true; return false; } /** @param array the array to check if it contains the other array's values * @param other the array to check if it is contained in the other array * @param the type of the containing array * @param the type of the contained array * @return if the second given array's values are completely contained in the first array */ public static boolean contains(T[] array, T2[] other, boolean identity) { for(T value : other) if(!contains(array, value, identity)) return false; return true; } /** @param array the array to check if it contains the other array's values * @param other the array to check if any of its values is contained in the other array * @param the type of the containing array * @param the type of the contained array * @return if any value from the second array is contained in the first array */ public static boolean containsAny(T[] array, T2[] other, boolean identity) { for(T value : other) if(contains(array, value, identity)) return true; return false; } /** shuffles the given array using {@link Noise#random(float, float)}, so the {@link Noise#setSeed(long) seed} influences the result * @param array the array to shuffle */ public static void shuffle(Object[] array) { for(int i = 0; i < array.length; i++) { int ii = (int) Noise.random(0, i + 1); Object temp = array[i]; array[i] = array[ii]; array[ii] = temp; } } /** @return an array of the unboxed values from the given values * @see #box(float[]) */ public static float[] unbox(Float[] values) { float[] unboxed = new float[values.length]; for(int i = 0; i < unboxed.length; i++) unboxed[i] = values[i]; return unboxed; } /** @return an array of the boxed values from the given values * @see #unbox(Float[]) */ public static Float[] box(float[] values) { Float[] boxed = new Float[values.length]; for(int i = 0; i < boxed.length; i++) boxed[i] = values[i]; return boxed; } /** @return an array of the unboxed values from the given values * @see #box(int[])*/ public static int[] unbox(Integer[] values) { int[] unboxed = new int[values.length]; for(int i = 0; i < unboxed.length; i++) unboxed[i] = values[i]; return unboxed; } /** @return an array of the boxed values from the given values * @see #unbox(Integer[]) */ public static Integer[] box(int[] values) { Integer[] boxed = new Integer[values.length]; for(int i = 0; i < boxed.length; i++) boxed[i] = values[i]; return boxed; } /** @return an array of the unboxed values from the given values * @see #box(boolean[])*/ public static boolean[] unbox(Boolean[] values) { boolean[] unboxed = new boolean[values.length]; for(int i = 0; i < unboxed.length; i++) unboxed[i] = values[i]; return unboxed; } /** @return an array of the boxed values from the given values * @see #unbox(Boolean[]) */ public static Boolean[] box(boolean[] values) { Boolean[] boxed = new Boolean[values.length]; for(int i = 0; i < boxed.length; i++) boxed[i] = values[i]; return boxed; } /** @param elements the elements to select from * @param start the array index of elements at which to start (may be negative) * @param everyXth select every xth of elements * @param output The array to put the values in. May be null. * @throws IllegalArgumentException if the given output array is not null and smaller than the required length * @return the output array or a new array (if output was null) containing everyXth element of the given elements array */ @SuppressWarnings("unchecked") public static T[] select(T[] elements, int start, int everyXth, T[] output) { int outputLength = 0; for(int i = start - 1; i < elements.length; i += everyXth) if(i >= 0) outputLength++; if(output == null) output = (T[]) new Object[outputLength]; if(output.length < outputLength) throw new IllegalArgumentException("The given output array is too small: " + output.length + "/" + outputLength); for(int oi = 0, i = start - 1; oi < outputLength; i += everyXth) if(i >= 0) output[oi++] = elements[i]; return output; } /** {@link #select(float[], int, int, float[])} starting at {@code everyXth - 1} * @see #select(float[], int, int, float[]) */ public static T[] select(T[] elements, int everyXth, T[] output) { return select(elements, 0, everyXth, output); } /** @see #select(Object[], int, int, Object[]) */ public static T[] select(T[] elements, int start, int everyXth) { return select(elements, start, everyXth, null); } /** @see #select(Object[], int, Object[]) */ public static T[] select(T[] elements, int everyXth) { return select(elements, everyXth, null); } /** selects the given {@code indices} from the given {@code elements} * @param elements the elements to select from * @param indices the indices to select from {@code select} * @param output The array to fill. May be null. * @return the selected {@code indices} from {@code elements} */ @SuppressWarnings("unchecked") public static T[] select(T[] elements, int[] indices, T[] output) { if(output == null) output = (T[]) new Object[indices.length]; if(output.length < indices.length) throw new IllegalArgumentException("The given output array is to small: " + output.length + "/" + indices.length); for(int i = 0; i < indices.length; i++) output[i] = elements[indices[i]]; return output; } /** @see #select(Object[], int[], Object[]) */ public static T[] select(T[] elements, int[] indices) { return select(elements, indices, null); } /** Skips, selects and goes to the next element repeatedly. Stops when {@code elements} has no more values. When {@code skips} has no more values, {@code repeatSkips} will be used repeatedly.
* If the length of the selection is the length of the given {@code elements}, {@code elements} is returned. * @param elements the elements from which to select not skipped ones * @param skips the number of indices to skip after each selection * @param repeatSkips The skips to use repeatedly after {@code skips} has no more values. If this is null, no more elements will be selected. * @param output the array to fill * @throws IllegalArgumentException if the output array is not null and smaller than the required length * @return the {@code elements} that were not skipped */ @SuppressWarnings("unchecked") public static T[] skipselect(T[] elements, int[] skips, int[] repeatSkips, T[] output) { boolean normal = skips != null && skips.length > 0, repeat = repeatSkips != null && repeatSkips.length > 0; if(!normal && !repeat) return elements; int length, span = 0, rsi = 0; for(length = 0; length < elements.length; length++) { int skip = normal && length < skips.length ? skips[length] : repeat ? repeatSkips[rsi >= repeatSkips.length ? rsi = 0 : rsi++] : Integer.MAX_VALUE - span - 1; if(span + skip + 1 <= elements.length) span += skip + 1; else break; } if(length == elements.length) return elements; if(output == null) output = (T[]) new Object[length]; if(output.length < length) throw new IllegalArgumentException("The given output array is too small: " + output.length + "/" + length); rsi = 0; for(int si = 0, ei = 0; si < length;) { output[si++] = elements[ei++]; if(si >= skips.length) if(repeat) ei += repeatSkips[rsi >= repeatSkips.length ? rsi = 0 : rsi++]; else break; else ei += skips[si]; } return output; } /** @see #skipselect(Object[], int[], int[], Object[]) */ public static T[] skipselect(T[] elements, int[] skips, int[] repeatSkips) { return skipselect(elements, skips, repeatSkips, null); } /** Like {@link #skipselect(Object[], int[], int[])} with a skips array that contains only {@code firstSkip} and an infinite {@code repeatSkips} array which elements are all {@code skips}. * If {@code skips} is smaller than 1, {@code elements} will be returned. * @throws IllegalArgumentException if the output array is not null and smaller than the required length * @see #skipselect(Object[], int[], int[]) */ @SuppressWarnings("unchecked") public static T[] skipselect(T[] elements, int firstSkip, int skips, T[] output) { int length, span = firstSkip; for(length = 0; length < elements.length; length++) if(span + skips + 1 <= elements.length) span += skips + 1; else { length++; break; } if(output == null) output = (T[]) new Object[length]; if(output.length < length) throw new IllegalArgumentException("The given output array is too small: " + output.length + "/" + length); for(int si = 0, ei = firstSkip; si < length; si++, ei += skips + 1) output[si] = elements[ei]; return output; } /** @see #skipselect(Object[], int, int, Object[]) */ public static T[] skipselect(T[] elements, int firstSkip, int skips) { return skipselect(elements, firstSkip, skips, null); } // primitive copies (probably get some generation tool) /** @param elements the elements to select from * @param start the array index of elements at which to start (may be negative) * @param everyXth select every xth of elements * @param output The array to put the values in. May be null. * @throws IllegalArgumentException if the given output array is not null and smaller than the required length * @return the output array or a new array (if output was null) containing everyXth element of the given elements array */ public static float[] select(float[] elements, int start, int everyXth, float[] output) { int outputLength = 0; for(int i = start - 1; i < elements.length; i += everyXth) if(i >= 0) outputLength++; if(output == null) output = new float[outputLength]; if(output.length < outputLength) throw new IllegalArgumentException("The given output array is too small: " + output.length + "/" + outputLength); for(int oi = 0, i = start - 1; oi < outputLength; i += everyXth) if(i >= 0) output[oi++] = elements[i]; return output; } /** {@link #select(float[], int, int, float[])} starting at {@code everyXth - 1} * @see #select(float[], int, int, float[]) */ public static float[] select(float[] elements, int everyXth, float[] output) { return select(elements, 0, everyXth, output); } /** @see #select(Object[], int, int, Object[]) */ public static float[] select(float[] elements, int start, int everyXth) { return select(elements, start, everyXth, null); } /** @see #select(Object[], int, Object[]) */ public static float[] select(float[] elements, int everyXth) { return select(elements, everyXth, null); } /** selects the given {@code indices} from the given {@code elements} * @param elements the elements to select from * @param indices the indices to select from {@code select} * @param output The array to fill. May be null. * @return the selected {@code indices} from {@code elements} */ public static float[] select(float[] elements, int[] indices, float[] output) { float[] selection = output == null ? new float[indices.length] : output; for(int i = 0; i < indices.length; i++) selection[i] = elements[indices[i]]; return selection; } /** @see #select(Object[], int[], Object[]) */ public static float[] select(float[] elements, int[] indices) { return select(elements, indices, null); } /** Skips, selects and goes to the next element repeatedly. Stops when {@code elements} has no more values. When {@code skips} has no more values, {@code repeatSkips} will be used repeatedly.
* If the length of the selection is the length of the given {@code elements}, {@code elements} is returned. * @param elements the elements from which to select not skipped ones * @param skips the number of indices to skip after each selection * @param repeatSkips The skips to use repeatedly after {@code skips} has no more values. If this is null, no more elements will be selected. * @param output the array to fill * @throws IllegalArgumentException if the output array is not null and smaller than the required length * @return the {@code elements} that were not skipped */ public static float[] skipselect(float[] elements, int[] skips, int[] repeatSkips, float[] output) { boolean normal = skips != null && skips.length > 0, repeat = repeatSkips != null && repeatSkips.length > 0; if(!normal && !repeat) return elements; int length, span = 0, rsi = 0; for(length = 0; length < elements.length; length++) { int skip = normal && length < skips.length ? skips[length] : repeat ? repeatSkips[rsi >= repeatSkips.length ? rsi = 0 : rsi++] : Integer.MAX_VALUE - span - 1; if(span + skip + 1 <= elements.length) span += skip + 1; else break; } if(length == elements.length) return elements; if(output == null) output = new float[length]; if(output.length < length) throw new IllegalArgumentException("The given output array is too small: " + output.length + "/" + length); rsi = 0; for(int si = 0, ei = 0; si < length;) { output[si++] = elements[ei++]; if(si >= skips.length) if(repeat) ei += repeatSkips[rsi >= repeatSkips.length ? rsi = 0 : rsi++]; else break; else ei += skips[si]; } return output; } /** @see #skipselect(Object[], int[], int[], Object[]) */ public static float[] skipselect(float[] elements, int[] skips, int[] repeatSkips) { return skipselect(elements, skips, repeatSkips, null); } /** Like {@link #skipselect(Object[], int[], int[])} with a skips array that contains only {@code firstSkip} and an infinite {@code repeatSkips} array which elements are all {@code skips}. * If {@code skips} is smaller than 1, {@code elements} will be returned. * @throws IllegalArgumentException if the output array is not null and smaller than the required length * @see #skipselect(Object[], int[], int[]) */ public static float[] skipselect(float[] elements, int firstSkip, int skips, float[] output) { int length, span = firstSkip; for(length = 0; length < elements.length; length++) if(span + skips + 1 <= elements.length) span += skips + 1; else { length++; break; } if(output == null) output = new float[length]; if(output.length < length) throw new IllegalArgumentException("The given output array is too small: " + output.length + "/" + length); for(int si = 0, ei = firstSkip; si < length; si++, ei += skips + 1) output[si] = elements[ei]; return output; } /** @see #skipselect(Object[], int, int, Object[]) */ public static float[] skipselect(float[] elements, int firstSkip, int skips) { return skipselect(elements, firstSkip, skips, null); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy