Udit Gogoi
Udit Gogoi

Reputation: 705

How to loop through a nested key value pair and filter it based on a array values

I have an array which is built from the user input. I am trying to loop through a nested key value pair and check whether the values in it matches any value of the given array. The purpose is to make a search facility.

My array :

FilteredSelectedOptions=["20180211","Trax","Vienna","AN01020"]

My key value pair is :

trips = {
  "20180201": [{
      "journeyId": 1001,
      "Number": "001",
      "DriverName": "Alex",
      "Transporter": {
        "id": "T1",
        "number": "AN01001",
        "Company": "Tranzient"
      },
      "place": [{
          "id": 001,
          "value": "Washington DC"
        },
        {
          "id": 002,
          "value": "Canberra"
        }
      ],
    },
    {
      "journeyId": 1002,
      "Number": "001",
      "DriverName": "Tom",
      "Transporter": {
        "id": "T2",
        "number": "AN01002",
        "Company": "Trax"
      },
      "place": [{
          "id": 2,
          "value": "Canberra"
        },
        {
          "id": 4,
          "value": "Vienna"
        }
      ],
    },
    {
      "journeyId": 1003,
      "Number": "004",
      "DriverName": "Jack",
      "Transporter": {
        "id": "T3",
        "number": "AN01003",
        "Company": "Trax"
      },
      "place": [{
        "id": 1,
        "value": "Washington DC",
      }, {
        "id": 4,
        "value": "Vienna",
      }],
    }
  ],
  "20180211": [{
      "journeyId": 1004,
      "Number": "005",
      "DriverName": "Jack",
      "Transporter": {
        "id": "T3",
        "number": "AN01013",
        "Company": "Trax"
      },
      "place": [{
          "id": 5,
          "value": "Bridgetown"
        },
        {
          "id": 6,
          "value": "Ottawa"
        },
        {
          "id": 4,
          "value": "Vienna"
        }
      ],

    },
    {
      "journeyId": 1005,
      "Number": "005",
      "DriverName": "Jerry",
      "Transporter": {
        "id": "T3",
        "number": "AN01020",
        "Company": "Trax"
      },
      "place": [{
          "id": 5,
          "value": "Bridgetown"
        },
        {
          "id": 6,
          "value": "Ottawa"
        }
      ],
    }
  ],
  "20180301": [{
    "journeyId": 1006,
    "Number": "005",
    "DriverName": "demy",
    "Transporter": {
      "id": "T3",
      "number": "AN01003",
      "Company": "Trax"
    },
    "place": [{
        "id": 5,
        "value": "Bridgetown"
      },
      {
        "id": 6,
        "value": "Ottawa"
      }
    ],
  }],
};

I am expecting output like this :

trips = {
    "20180201": 
        [{
           "journeyId": 1002,
            "Number": "001",
            "DriverName":"Tom",
            "Transporter": {
                "id": "T2",
                "number": "AN01002",
                "Company": "Trax"
            },
            "place": [{"id":002,"value":"Canberra" }]
                      [{"id":004,"value":"Vienna"}]
        },
        {
             "journeyId": 1003,
            "Number": "004",
            "DriverName":"Jack",
            "Transporter": {
                "id": "T3",
                "number": "AN01003",
                "Company": "Trax"
            },
            "place": [{"id":001,"value":"Washington DC" }]
                      [{"id":004,"value":"Vienna"}]
        }],
    "20180211": [{
             "journeyId": 1004,
            "Number": "005",
            "DriverName":"Jack",
            "Transporter": {
                "id": "T3",
                "number": "AN01013",
                "Company": "Trax"
            },
            "place": [{"id":005,"value":"Bridgetown" }]
                      [{"id":006,"value":"Ottawa"}]
                      [{"id":004,"value":"Vienna"}]

        },
        {
      "journeyId": 1005,
      "Number": "005",
      "DriverName": "Jerry",
      "Transporter": {
        "id": "T3",
        "number": "AN01020",
        "Company": "Trax"
      },
      "place": [{
          "id": 5,
          "value": "Bridgetown"
        },
        {
          "id": 6,
          "value": "Ottawa"
        }
       ]

};

I am trying to use a for loop to check each array elements against the key value pair. What I want to do basically is

for (option in FilteredselectedOptions) 
{
     //logic
}

I have been able to do it for one particular array value:

const filteredTrips = Object.keys(trips).reduce((tmp, x) => {
  const filtered = trips[x].filter(y => y.place && y.place.some(z => z.value === 'Vienna'));

  if (filtered.length) {
    tmp[x] = filtered;
  }

  return tmp;
}, {});

But how do I do it for all array elements irrespective of how many elements are inside array. Please help in the loop.

Upvotes: 1

Views: 224

Answers (3)

Nina Scholz
Nina Scholz

Reputation: 386680

Just an approach by trying to filter with finding a single item in the data.

function filter(object, options) {
    const check = v => options.includes(v) || v && typeof v === 'object' && Object.keys(v).some(l => check(v[l]));
    var result = {};
    Object.keys(object).forEach(function (k) {
        var temp = options.includes(k)
            ? object[k]
            : object[k].filter(check);

        if (temp.length) {
            result[k] = temp;
        }
    });
    return result;
}

var trips = { "20180201": [{ journeyId: 1001, Number: "001", DriverName: "Alex", Transporter: { id: "T1", number: "AN01001", Company: "Tranzient" }, place: [{ id: "001", value: "Washington DC" }, { id: "002", value: "Canberra" }] }, { journeyId: 1002, Number: "001", DriverName: "Tom", Transporter: { id: "T2", number: "AN01002", Company: "Trax" }, place: [{ id: 2, value: "Canberra" }, { id: 4, value: "Vienna" }] }, { journeyId: 1003, Number: "004", DriverName: "Jack", Transporter: { id: "T3", number: "AN01003", Company: "Trax" }, place: [{ id: 1, value: "Washington DC" }, { id: 4, value: "Vienna" }] }], "20180211": [{ journeyId: 1004, Number: "005", DriverName: "Jack", Transporter: { id: "T3", number: "AN01013", Company: "Trax" }, place: [{ id: 5, value: "Bridgetown" }, { id: 6, value: "Ottawa" }, { id: 4, value: "Vienna" }] }, { journeyId: 1005, Number: "005", DriverName: "Jerry", Transporter: { id: "T3", number: "AN01020", Company: "Trax" }, place: [{ id: 5, value: "Bridgetown" }, { id: 6, value: "Ottawa" }] }], "20180301": [{ journeyId: 1006, Number: "005", DriverName: "demy", Transporter: { id: "T3", number: "AN01003", Company: "Trax" }, place: [{ id: 5, value: "Bridgetown" }, { id: 6, value: "Ottawa" }] }] },
    options = ["20180211", /* "Trax", */ "Vienna", "AN01020"];

console.log(filter(trips, options));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

Alon Parag
Alon Parag

Reputation: 137

Let me know if you want a complete code. Lets begin that objects in javascript don't have built in filter or reduce methods, only arrays do. What I would do, I would loop through the object properties, which are arrays, and check if they have one of the properties that are found in the FilteredSelectedOptions. If I find one, I will push it to a new array containing the results.

Upvotes: 0

Jonas Wilms
Jonas Wilms

Reputation: 138417

One could use recursion to search for values in an object:

 function hasValue(obj, values){
  for(const value of Object.values(obj)){
    if(typeof value === "object"){
       if(hasValue(value, values))
          return true;
    } else {
       if(values.includes(value))
          return true;
    }
  }
  return false;
 }

Now we could filter your trips by comparing the keys and using the function above:

  const filteredTrips = Object.keys(trips).filter(key => {
    if(FilteredSelectedOptions.includes(key))
       return true;
    if(hasValue(trips[key], FilteredSelectedOptions))
       return true;
    return false;
 });

Upvotes: 1

Related Questions