package eu.dnetlib.miscutils.collections;

import java.util.Map;

import eu.dnetlib.miscutils.functional.UnaryFunction;

/**
 * A special case of a PositionalMapGenerator, bound for String values. It provides automatic split which returns an
 * iterable of maps.
 * 
 * @author marko
 * 
 * @param <K>
 *            key
 */
public class PositionalStringMapGenerator<K> extends PositionalMapGenerator<K, String> {

	/**
	 * Creates a new positional string map generator
	 * 
	 * @param keys
	 */
	public PositionalStringMapGenerator(final K... keys) {
		super(keys);
	}

	/**
	 * Pass a list of strings and return a list of maps where each key has a value according to the position in the
	 * splitted array relative to the position of the key in the constructor.
	 * 
	 * @param elements
	 *            list of strings which will be splitted
	 * @param separator
	 *            separator
	 * @return iterable of maps contained splitted values
	 */
	public Iterable<Map<K, String>> split(Iterable<String> elements, final String separator) {

		return new MappedCollection<Map<K, String>, String>(elements, new UnaryFunction<Map<K, String>, String>() {

			@Override
			public Map<K, String> evaluate(String value) {
				return asMap(value.split(separator));
			}
		});

	}

	/**
	 * Pass a list of strings and return a list of objects constructed by passing the splitted string values to the
	 * constructor of the new object.
	 * 
	 * <p>
	 * This method doesn't need to setup a list of key names in the constructor
	 * </p>
	 * 
	 * @param <X>
	 *            some class
	 * @param clazz
	 *            some class
	 * @param elements
	 *            list of strings to split
	 * @param separator
	 *            separator
	 * @return iterable of instances of some class constructed with splitted values
	 */
	public <X> Iterable<X> split(final Class<X> clazz, Iterable<String> elements, final String separator) {

		return new MappedCollection<X, String>(elements, new UnaryFunction<X, String>() {

			@Override
			public X evaluate(String value) {
				return construct(clazz, String.class, value.split(separator));
			}
		});

	}
}
