/* * Apache License * Version 2.0, January 2004 * http://www.apache.org/licenses/ * * Copyright 2013 Aurelian Tutuianu * Copyright 2014 Aurelian Tutuianu * Copyright 2015 Aurelian Tutuianu * Copyright 2016 Aurelian Tutuianu * * 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 rapaio.data; import java.util.stream.Collectors; /** * A variable which wraps rows from another variable. The row selection * and order is specified by a mapping given at construction time. * <p> * This variable does not hold actual values, it delegates the behavior to the * wrapped variable, thus the wrapping affects only the rows selected and the * order of these rows. * <p> * Mapped variables does not allows adding new values * * @author <a href="mailto:padreati@yahoo.com">Aurelian Tutuianu</a> */ public class MappedVar extends AbstractVar { /** * Builds a mapped variable specifying selected positions through a mapping * * @param source wrapped variable * @param mapping mapping of indexed values * @return mapped variable */ public static MappedVar byRows(Var source, Mapping mapping) { return new MappedVar(source, mapping); } /** * Build a mapped variable specifying the selected positions through a variable array * * @param source wrapped variable * @param rows variable array of indexed values * @return mapped variable */ public static MappedVar byRows(Var source, int... rows) { return new MappedVar(source, Mapping.copy(rows)); } private static final long serialVersionUID = -2293127457462742840L; private final Var source; private final Mapping mapping; private MappedVar(Var var, Mapping mapping) { withName(var.name()); if (var instanceof MappedVar) { this.mapping = Mapping.wrap(mapping.rowStream().map(row -> ((MappedVar) var).mapping().get(row)).mapToObj(row -> row).collect(Collectors.toList())); this.source = ((MappedVar) var).source(); } else { this.mapping = mapping; this.source = var; } } @Override public VarType type() { return source.type(); } @Override public int rowCount() { return mapping.size(); } @Override public void addRows(int rowCount) { throw new IllegalArgumentException("operation not available on mapped vectors"); } public Var source() { return source; } public Mapping mapping() { return mapping; } @Override public double value(int row) { return source.value(mapping.get(row)); } @Override public void setValue(int row, double value) { source.setValue(mapping.get(row), value); } @Override public void addValue(double value) { throw new IllegalArgumentException("operation not available on mapped vectors"); } @Override public int index(int row) { return source.index(mapping.get(row)); } @Override public void setIndex(int row, int value) { source.setIndex(mapping.get(row), value); } @Override public void addIndex(int value) { throw new IllegalArgumentException("operation not available on mapped vectors"); } @Override public String label(int row) { return source.label(mapping.get(row)); } @Override public void setLabel(int row, String value) { source.setLabel(mapping.get(row), value); } @Override public void addLabel(String value) { throw new IllegalArgumentException("operation not available on mapped vectors"); } @Override public String[] levels() { return source.levels(); } @Override public void setLevels(String[] dict) { source.setLevels(dict); } @Override public boolean binary(int row) { return source.binary(mapping.get(row)); } @Override public void setBinary(int row, boolean value) { source.setBinary(mapping.get(row), value); } @Override public void addBinary(boolean value) { throw new IllegalArgumentException("operation not available on mapped vectors"); } @Override public long stamp(int row) { return source.stamp(mapping.get(row)); } @Override public void setStamp(int row, long value) { source.setStamp(mapping.get(row), value); } @Override public void addStamp(long value) { throw new IllegalArgumentException("operation not available on mapped vectors"); } @Override public boolean missing(int row) { return source.missing(mapping.get(row)); } @Override public void setMissing(int row) { source.setMissing(mapping.get(row)); } @Override public void addMissing() { throw new IllegalArgumentException("operation not available on mapped vectors"); } @Override public void remove(int row) { mapping.remove(row); } @Override public void clear() { mapping.clear(); } @Override public Var newInstance(int rows) { return source.newInstance(rows); } @Override public String toString() { return "MappedVar:" + source.type() + "[name:" + name() + ", rowCount:" + mapping.size() + ']'; } }