f8d9f22ac79fba7f0ceb26e1e737b0b1c116490f kent Wed Feb 4 23:07:26 2015 -0800 Added functions to index a field. diff --git src/lib/fieldedTable.c src/lib/fieldedTable.c index 2c9fb17..5037bcd 100644 --- src/lib/fieldedTable.c +++ src/lib/fieldedTable.c @@ -1,25 +1,26 @@ /* fieldedTable - a table composed of untyped strings in memory. Includes names for each * field. This is a handy way of storing small-to-medium tab-separated files that begin * with a "#list of fields" line among other things. */ /* Copyright (C) 2013 The Regents of the University of California * See README in this or parent directory for licensing information. */ #include "common.h" #include "localmem.h" #include "linefile.h" +#include "hash.h" #include "fieldedTable.h" struct fieldedTable *fieldedTableNew(char *name, char **fields, int fieldCount) /* Create a new empty fieldedTable with given name, often a file name. */ { struct fieldedTable *table; AllocVar(table); struct lm *lm = table->lm = lmInit(0); table->name = lmCloneString(lm, name); table->cursor = &table->rowList; table->fieldCount = fieldCount; int i; char **row = lmAllocArray(lm, table->fields, fieldCount); for (i=0; ilineIx); } /* Clean up and go home. */ lineFileClose(&lf); return table; } +int fieldedTableMustFindFieldIx(struct fieldedTable *table, char *field) +/* Find index of field in table's row. Abort if field not found. */ +{ +int ix = stringArrayIx(field, table->fields, table->fieldCount); +if (ix < 0) + errAbort("Field %s not found in table %s", field, table->name); +return ix; +} + +struct hash *fieldedTableIndex(struct fieldedTable *table, char *field) +/* Return hash of fieldedRows keyed by values of given field */ +{ +int fieldIx = fieldedTableMustFindFieldIx(table, field); +struct hash *hash = hashNew(0); +struct fieldedRow *fr; +for (fr = table->rowList; fr != NULL; fr = fr->next) + { + hashAdd(hash,fr->row[fieldIx], fr); + } +return hash; +} + +struct hash *fieldedTableUniqueIndex(struct fieldedTable *table, char *field) +/* Return hash of fieldedRows keyed by values of given field, which must be unique. */ +{ +int fieldIx = fieldedTableMustFindFieldIx(table, field); +struct hash *hash = hashNew(0); +struct fieldedRow *fr; +for (fr = table->rowList; fr != NULL; fr = fr->next) + { + char *key = fr->row[fieldIx]; + if (hashLookup(hash, key)) + errAbort("%s duplicated in %s field of %s", key, field, table->name); + hashAdd(hash,fr->row[fieldIx], fr); + } +return hash; +} +