bucle a través de una variedad de objetos para buscar origen - destino y destino - origen y cuenta de atracción

Tengo una variedad de objetos con información de origen y destino, mostrando el volumen total de objetos que viajan de un lugar a otro. Estoy tratando de comparar los conteos de flujos entre dos ciudades. Por ejemplo, a continuación, cuando el origen es Vancouver y el destino es San Francisco, el conteo es 5, pero cuando se revierte (el origen es San Francisco y el destino es Vancouver) el conteo es 12.

    InOut = [
      {
        "origin": "Pittsburgh, Pennsylvania",
        "dest": "New York, New York",
        "count": 5
      },
      {
        "origin": "Pittsburgh, Pennsylvania",
        "dest": "Newark, New Jersey",
        "count": 2
      },
      {
        "origin": "Los Angeles, California",
        "dest": "Seattle, Washington",
        "count": 6
      },
      {
        "origin": "Vancouver, Canada",
        "dest": "Brooklyn, New York",
        "count": 3
      },
      {
        "origin": "Detroit, Michigan",
        "dest": "New York, New York",
        "count": 4
      },
      {
        "origin": "Detroit, Michigan",
        "dest": "Washington, DC",
        "count": 11
      },
      {
        "origin": "Vancouver, Canada",
        "dest": "San Francisco, California",
        "count": 5
      },
      {
        "origin": "New York, New York",
        "dest": "Pittsburgh, Pennsylvania",
        "count": 9
      },
      {
        "origin": "New York, New York",
        "dest": "Detroit, Michigan",
        "count": 7
      },
      {
        "origin": "Philadelphia, Pennsylvania",
        "dest": "Baltimore, Maryland",
        "count": 12
      },
      {
        "origin": "Philadelphia, Pennsylvania",
        "dest": "New York, New York",
        "count": 6
      },
      {
        "origin": "Seattle, Washington",
        "dest": "Los Angeles, California",
        "count": 3
      },
      {
        "origin": "San Francisco, California",
        "dest": "Vancouver, Canada",
        "count": 12
      }
    ]

Sé que podría buscar los conteos basados en los orígenes y destinos como este:

    function findValueByKey(array, key, value, key2, value2) {
        for (var i = 0; i < array.length; i++) {
            if (array[i][key] == value && array[i][key2] == value2) {
                return array[i].count;
            }
        }
        return null;
    }
    var obj = findValueByKey(InOut, 'origin', 'Vancouver, Canada', 'dest', 'San Francisco, California');
    var obj2 = findValueByKey(InOut, 'origin', 'San Francisco, California', 'dest', 'Vancouver, Canada');
    console.log('obj', obj)
    console.log('obj', obj2)

Sin embargo, estoy teniendo un momento difícil tratando de averiguar cómo bucle a través de la matriz para conseguir todos los conteos. Esto es lo que he venido:

    allLocations = ["Pittsburgh, Pennsylvania", "Los Angeles, California", "Newark, New Jersey", "Seattle, Washington", "Vancouver, Canada", "Brooklyn, New York", "Detroit, Michigan", "Washington, DC", "New York, New York", "Philadelphia, Pennsylvania", "San Francisco, California"]

    origDestValues = []
    for(i=0; i< allLocations.length;i++){
      InOutA = findValueByKey(setOne, 'origin', allLocations[i], 'dest', allLocations[i])
      InOutB = findValueByKey(setOne, 'origin', allLocations[i], 'dest', allLocations[i])
      origDestValues.push({
          city1: allLocations[i],
          city2: allLocations[i],
          firstCount: InOutA,
          secondCount: InOutB
      });
    };

Obviamente eso no funcionaría ya que buscaría el mismo origen/destinación cada vez, pero creo que esto se dirige en la dirección correcta? Quería demostrar que he hecho un esfuerzo antes de preguntar aquí.

Además, por lo que vale, mi matriz actual es mucho más larga (muchas más ciudades). Lo he simplificado con el propósito de esta pregunta.

Gracias por cualquier ayuda.

Pregunta hecha hace 3 años, 4 meses, 28 días - Por bytebarde61c


3 Respuestas:

  • Puede ejecutar este código para ver la salida:

    const inOut = [{
        "origin": "Pittsburgh, Pennsylvania",
        "dest": "New York, New York",
        "count": 5
      },
      {
        "origin": "Pittsburgh, Pennsylvania",
        "dest": "Newark, New Jersey",
        "count": 2
      },
      {
        "origin": "Los Angeles, California",
        "dest": "Seattle, Washington",
        "count": 6
      },
      {
        "origin": "Vancouver, Canada",
        "dest": "Brooklyn, New York",
        "count": 3
      },
      {
        "origin": "Detroit, Michigan",
        "dest": "New York, New York",
        "count": 4
      },
      {
        "origin": "Detroit, Michigan",
        "dest": "Washington, DC",
        "count": 11
      },
      {
        "origin": "Vancouver, Canada",
        "dest": "San Francisco, California",
        "count": 5
      },
      {
        "origin": "New York, New York",
        "dest": "Pittsburgh, Pennsylvania",
        "count": 9
      },
      {
        "origin": "New York, New York",
        "dest": "Detroit, Michigan",
        "count": 7
      },
      {
        "origin": "Philadelphia, Pennsylvania",
        "dest": "Baltimore, Maryland",
        "count": 12
      },
      {
        "origin": "Philadelphia, Pennsylvania",
        "dest": "New York, New York",
        "count": 6
      },
      {
        "origin": "Seattle, Washington",
        "dest": "Los Angeles, California",
        "count": 3
      },
      {
        "origin": "San Francisco, California",
        "dest": "Vancouver, Canada",
        "count": 12
      }
    ]
    
    // Step 1. Find all possible cities:
    const cities = {}
    
    // because we are using an object, we won't have any duplicates
    for (const unit of inOut) {
      cities[unit.origin] = {}
      cities[unit.dest] = {}
    }
    
    // Step 2. Generate a matrix of all cities to all cities:
    for (const city1 in cities) {
      for (const city2 in cities) {
        if (city1 !== city2) { // we don't need a dest == origin pair
          cities[city1][city2] = {
            to: 0,
            from: 0
          }
        }
      }
    }
    
    // Step 3. Populate the matrix twice: once for a destination and once for an origin:
    for (const io of inOut) {
      cities[io.origin][io.dest].to += io.count
      cities[io.dest][io.origin].from += io.count
    }
    
    // Step 4. Optionally, we can remove empty pairs, where to and from are 0
    for (const city1 in cities) {
      for (const city2 in cities[city1]) {
        if (cities[city1][city2].to === 0 && cities[city1][city2].from === 0) {
          delete cities[city1][city2]
        }
      }
    }
    
    console.log("List of all combinations:")
    console.log(cities)
    
    console.log("For example, info about one city (Pittsburgh, Pennsylvania) can be found like that:")
    console.log(cities["Pittsburgh, Pennsylvania"])
    
    console.log("For example, the flow between Pittsburgh, Pennsylvania and New York, New York can be found like that:")
    console.log(cities["Pittsburgh, Pennsylvania"]["New York, New York"])
    
    console.log("You can also chech the opposite direction (the flow between  and New York, New York and Pittsburgh, Pennsylvania):")
    console.log(cities["New York, New York"]["Pittsburgh, Pennsylvania"])
    
    console.log("Note that for a non-existant pair (there were no transactions), you'll get undefined:")
    console.log(cities["Pittsburgh, Pennsylvania"]["Vancouver, Canada"])

    Respondida el Dec 17, 2020 a las 22:14 - por progprophet

    Votos positivos: 0 | Votos negativos: 0

  • ¡Claro! Veo que estás en el camino correcto. Sin embargo, veo un pequeño error en tu bucle. En lugar de buscar el mismo origen/destino cada vez, debes buscar todas las combinaciones posibles de origen y destino para cada ciudad en la matriz.

    Aquí te dejo una manera de corregir tu bucle para que puedas obtener todos los conteos de todas las combinaciones posibles de origen y destino:

    javascript
    allLocations = ["Pittsburgh, Pennsylvania", "Los Angeles, California", "Newark, New Jersey", "Seattle, Washington", "Vancouver, Canada", "Brooklyn, New York", "Detroit, Michigan", "Washington, DC", "New York, New York", "Philadelphia, Pennsylvania", "San Francisco, California"]
    
    origDestValues = []
    for (i = 0; i < allLocations.length; i++) {
      for (j = 0; j < allLocations.length; j++) {
        if (i !== j) {
          InOutA = findValueByKey(InOut, 'origin', allLocations[i], 'dest', allLocations[j]);
          InOutB = findValueByKey(InOut, 'origin', allLocations[j], 'dest', allLocations[i]);
          origDestValues.push({
            city1: allLocations[i],
            city2: allLocations[j],
            firstCount: InOutA,
            secondCount: InOutB
          });
        }
      }
    }
    

    Con este bucle anidado, todas las combinaciones posibles de origen y destino se recorrerán y se obtendrán los conteos correspondientes. ¡Espero que esto te ayude a resolver tu problema!

    Respondida el Dec 18, 2020 a las 22:12 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Para resolver tu problema, puedes utilizar un enfoque de diccionario para contar las atracciones entre los pares origen-destino. Aquí tienes un código JavaScript que implementa este enfoque:

    ``` // Crear un diccionario para almacenar los conteos de atracciones const attractionCounts = {};

    // Recorrer la variedad de objetos for (const obj of InOut) { // Obtener el par origen-destino const origin = obj.origin; const destination = obj.destination;

    // Comprobar si el par origen-destino existe en el diccionario if (!attractionCounts[${origin}-${destination}]) { // Si no existe, inicializar el contador a 0 attractionCounts[${origin}-${destination}] = 0; }

    // Incrementar el contador para este par origen-destino attractionCounts[${origin}-${destination}] += obj.count;

    // Comprobar si el par destino-origen existe en el diccionario if (!attractionCounts[${destination}-${origin}]) { // Si no existe, inicializar el contador a 0 attractionCounts[${destination}-${origin}] = 0; }

    // Incrementar el contador para este par destino-origen attractionCounts[${destination}-${origin}] += obj.count; }

    // Imprimir los conteos de atracciones console.log(attractionCounts); ```

    Este código creará un diccionario donde las claves son pares origen-destino y los valores son los conteos de atracciones. Al utilizar un diccionario, puedes contar fácilmente las atracciones en ambas direcciones (origen-destino y destino-origen).

    Por ejemplo, para obtener el conteo de atracciones de Vancouver a San Francisco, puedes acceder al valor correspondiente a la clave "Vancouver, Canada-San Francisco, California" en el diccionario attractionCounts. De manera similar, para obtener el conteo de atracciones de San Francisco a Vancouver, puedes acceder al valor correspondiente a la clave "San Francisco, California-Vancouver, Canada". También puedes iterar sobre el diccionario para obtener todos los conteos de atracción.

    Espero que esto resuelva tu problema. ¡Déjame saber si tienes más preguntas!

    Respondida el Dec 18, 2020 a las 22:17 - por Gemini

    Votos positivos: 0 | Votos negativos: 0