c# leyendo todas las entradas del mismo valor en el diccionario/

nuevo en C #. Estoy tratando de crear un sistema simple en el que pueda buscar en una lista de objetos y cuándo pertenece a una determinada ID. Póngalo en una Lista/ArrayList para que pueda leerlo/hacer cualquier otra cosa.

Cada "elemento" tiene un ID de ubicación. Cuando entro en esta ubicación y presiono "mirar". El programa debe verificar en qué ubicación estoy y sacar solo los "elementos" con la misma identificación.

En practica. La lista de elementos será bastante grande (y las ubicaciones también). Así que parece un desperdicio de procesamiento revisar la lista una y otra vez. Por eso pensé en usar un diccionario. Pero parece que no puedo acceder a varias entradas en el diccionario, solo en un lugar específico.

por ejemplo:

Dictionary<string, int> itemLoc = new Dictionary<string, int>();
itemLoc.Add("pen", 011);
itemLoc.Add("paper", 011);
itemLoc.Add("tv remote", 012);

//print everything in location 011

Lo siento por la falta de código. Todavía estoy averiguando cómo entender esto. He estado investigando ArrayLists, Lists, Hashtables y estos diccionarios. Pero con ninguno he podido lograr lo que busco de manera efectiva.

Podría hacer un foreach y verificar cada entrada. Pero como se mencionó anteriormente. Eso parecería un desperdicio de procesamiento.

¿Alguna idea o consejo? Un empujón en la dirección correcta en cuanto al código sería muy apreciado.

preguntado el 12 de junio de 12 a las 16:06

¿Hay alguna razón por la que no los coloque en una base de datos y haga su consulta allí? Parecería una solución razonable para esto (y probablemente más fácil de mantener a largo plazo). -

7 Respuestas

Lo que está haciendo es almacenar valores enteros en ubicaciones especificadas por los valores hash de las claves de cadena que está utilizando.

Una mejor idea sería usar Dictionary<int, List<string>> (o lo que sea que tenga C# para una clase de lista), haz algo como itemLoc.Add(011, new List<string>()); itemLoc.Get(011).Add("pen"); cuando agrega el primer elemento en una ubicación (por lo que primero querrá verificar si la ubicación existe como una clave en el diccionario), y luego simplemente itemLoc.Get(011).Add("paper"); después.

Tenga en cuenta que mi sintaxis puede no ser correcta ya que no he usado C# yo mismo, pero no debería ser tan diferente. Y si la clase de diccionario de C# tiene un AddIfAbsent()-type, que sería útil para simplificar la verificación de claves que mencioné.

Respondido el 12 de junio de 12 a las 16:06

No nos ha proporcionado suficiente información sobre las limitaciones de su problema. A Dictionary<string, List<string>> funcionará más rápido, pero no ha identificado si puede tener varios elementos en varias ubicaciones (por ejemplo, ¿el "papel" puede estar en 011 y 012 o solo en 011?) En ese caso, cada vez que agregue tendrá que asegúrese de que ese artículo no esté ya en otra ubicación.

Un enfoque muy simplificado sería desglosarlo de manera muy simple y optimizarlo en función de los resultados.

class MyItem
{
    public string Name { get; set; }
    public string Location { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        List<MyItem> myItems = new List<MyItem>()
        {
            new MyItem() { Location = "011", Name = "pen" },
            new MyItem() { Location = "011", Name = "paper" },
            new MyItem() { Location = "012", Name = "tv remote" }
        };

        var specificItems = myItems.Where(f => f.Location == "011");

        foreach (var item in specificItems)
        {
            Console.WriteLine(item.Name);
        }

        Console.Read();
    }
}

Una vez que realice su punto de referencia, puede considerar cambiarlo a algo (tal vez un Dictionary<string, List<string>>

Respondido el 12 de junio de 12 a las 16:06

Sí, cada objeto solo puede estar en un lugar al mismo tiempo. ¿Es esto lo suficientemente eficiente/rápido como para hacerlo varias veces por minuto cuando la cantidad de ubicaciones será de más de 20 y los artículos superarán los 400? - Twan Mul

@TwanMul: Eso es bastante pequeño. Debería ser lo suficientemente rápido para su uso en ese caso. Puede realizar algunas evaluaciones comparativas básicas utilizando el Stopwatch clase. - bryan crosby

Un diccionario, por definición, tiene un valor para cada clave. No se puede acceder a varios valores con una sola clave.

Sin embargo, puede utilizar una Lista como valor. Por lo tanto, si desea crear una colección de elementos en la misma ubicación y reutilizarlos más tarde, puede almacenarlos en un diccionario donde la clave es ID de ubicación: Diccionario>

Espero que ayude

Respondido el 12 de junio de 12 a las 16:06

Diccionario proporciona mapeo del la tecla a el valor, pero no al revés. Puede crear otro diccionario que tenga los identificadores de ubicación como clave y una colección de elementos como valor y buscar el identificador de ubicación de esa manera

Respondido el 12 de junio de 12 a las 16:06

Un diccionario le permitirá encontrar el elemento en función de la ubicación de manera eficiente, o la ubicación en función del elemento de manera eficiente, pero no ambos. (Eso no quiere decir que no sea terriblemente ineficiente hacerlo de otra manera, solo menos y generalmente O (n) en lugar de algo más rápido).

Entonces, tienes un par de posibilidades. El más simple es simplemente iterar sobre itemLoc.Values y busca lo que quieres. Más complejo sería mantener una segunda colección, una Dictionary<int, List<string>>, que almacenaría la lista completa de elementos por ubicación. Esto hará que las búsquedas sean muy rápidas y fáciles a costa de más trabajo para mantener los datos (inserciones, actualizaciones, eliminaciones).

Se trata de lo que desea optimizar. En el caso más extremo, podrías deshacerte del Dictionary<string,int> y utilice el Dictionary<int, List<string>> exclusivamente, buscando eso cuando necesite encontrar la ubicación de un elemento, pero solo querrá hacerlo si ese tipo de búsqueda es muy raro.

Respondido el 12 de junio de 12 a las 16:06

Yo lo recomiendo

Dictionary<int, List<string>>

De esta manera, puede agregar varios elementos a cada ubicación

p.ej

var locItems = new Dictionary<int, List<string>>();

List<string> items = new List<string>() { "item1", "Item2", "item3" };

locItems.Add(1, items);

// Get all items from location 1 ...
List<string> items = locItems[1];

foreach(string s in items)
    Console.WriteLine(s);

// Now add another item to the list
items.Add("Some new item");

// Since this is by ref - the list in the dict will be modified 
// so you don't need to worry about re-adding it to the dict

Respondido el 12 de junio de 12 a las 16:06

¡gracias por su respuesta! una pequeña pregunta de novato. var locItems : ¿var significa que puedo elegir mi propio var, o es así como lo escribes? para el primero, que var recomendarias. - Twan Mul

var es solo una declaración de variable de tipo implícitamente, es decir, el uso infiere el tipo. Podría escribir string mystring = "bob", o podría escribir var mystring = "bob". Ambos equivalen a lo mismo ya que asignar el valor "bob" a la variable infiere que el tipo de la variable es una cadena. Podrías cambiar la lista de líneas elementos = elementosubicados[1]; para var artículos = locItems[1]; porque locItems[1] devolvería una Lista y, por lo tanto, el tipo de "elementos" se deduciría del uso: Charleh

Por la forma en que se ve el código ahora, solo se le permitirá tener un solo bolígrafo, papel, etc. Esto se debe a que los está utilizando como claves para el diccionario. Una mejor manera de lograr esta tarea sería tener un

Dictionary<int, List<string>>

El int sería el id de la habitación (001, 011, ect) y la lista sería el objeto almacenado en cada habitación. Dada la identificación de la habitación, ahora puede recorrer la lista de todas las cosas almacenadas en esa habitación.

Respondido el 12 de junio de 12 a las 16:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.