public static bool Collect <T, U>(INumberColumn <T> indices, IColumn <U> values, BitVector unusedValues) where T : unmanaged, IEquatable <T> { IRemapper <T> remapper = RemapperFactory.Build <T>(); // Trim indices first to consolidate references into a new consolidated array as much as possible indices.Trim(); // Find all value indices which are no longer referenced by any row indices.ForEach((slice) => remapper.RemoveValues(slice, unusedValues)); // If there are unused values, ... int[] remapped = unusedValues.ToArray(); if (remapped.Length > 0) { int remapFrom = (values.Count - remapped.Length); // Swap the *values* to the end of the values array for (int i = 0; i < remapped.Length; ++i) { values.Swap(remapFrom + i, remapped[i]); } // Swap indices using those values to use the new ones indices.ForEach((slice) => remapper.RemapAbove(slice, remapFrom, remapped)); // Remove the unused values that are now at the end of the array values.RemoveFromEnd(remapped.Length); } // Trim values afterward to clean up any newly unused space values.Trim(); // Return whether anything was remapped return(remapped.Length > 0); }
/// <summary> /// FindUnusedAndCollect walks all values in the 'indices' column to find any indices with /// no remaining references. It then swaps and removes them from the 'values' column and /// updates indices in the 'indices' column to the updated values for all swapped rows. /// /// This overload uses the provided BitVector to mark used rows. The caller can set BitVector /// entries true to keep specific rows even if they aren't referenced in the indices column. /// </summary> /// <typeparam name="T">Type of index used (int or byte)</typeparam> /// <param name="values">Column containing the values themselves</param> /// <param name="indices">Column containing indices referring to rows in the values column</param> /// <param name="rowsToKeep">BitVector to use to track referenced rows; values already set true will be kept even if unreferenced.</param> /// <returns>True if any values were swapped and removed; false otherwise.</returns> public static bool FindUnusedAndCollect <T>(IColumn values, INumberColumn <T> indices, BitVector rowsToKeep) where T : unmanaged, IEquatable <T> { IRemapper <T> remapper = RemapperFactory.Build <T>(); // Trim indices first to consolidate references into a new consolidated array as much as possible indices.Trim(); // Find all value indices which are no longer referenced by any row indices.ForEach((slice) => remapper.AddValues(slice, rowsToKeep)); return(Collect(values, new[] { indices }, rowsToKeep)); }