Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript - search array of nested objects and return parent if value is found in child [duplicate]

There is an array of objects (489 objects). An object has a key which has another object (child object). Number of child object is indefinite.

I've created a fiddle as well. Please find below search function:

function getObjects(obj, key, val) {
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            parent = obj;
            objects = objects.concat(getObjects(obj[i], key, val));    
        } else {
            if(obj[i].toString().toLowerCase().indexOf(val.toString().toLowerCase()) > -1) {
                objects.push(obj);
            }
        } 
    }
    return objects;
} 

Here I want to search for a search string in an array of object including nested object (asset_info) as well. The search without getObjects works fine with below function.

    this.data.filter(function(row){ 
        var flag; 
        for(var prop in (columns.length > 0 ? columns : row)){ 
          flag = false; 
          flag = row[columns.length > 0 ? columns[prop] : 
prop].toString().toLowerCase().indexOf(searchString.toString().toLowerCase()) > -1; 
          if(flag) 
          break; 
        } 
    return flag;

In above function I am not able to search within nested object (asset_info). And so I have been using getObject function which I found online.

Now the issue is I am not able to search including asset_info but not able to return its parent. For example in fiddle, if I search for emc, search should return 2nd object from data.

Update: still not able to return parent of a child where search string has been found

** Update 2 **

var data = [
{
  'booking_name': 'gtec/1101822/lmikdy/ls-rmea/oss11',
  'asset_count': 2,
  'pdg': 'Invalid',
  'user_area': 'Invalid',
  'deployment_number': 'Invalid',
  'spoc': 'invalid',
  'release': 'Invalid',
  'start_date': '2017-06-12 00:00:00',
  'end_date': '2017-06-16 00:00:00',
  'asset_info': [
    {
      'bams_id': 'BAMS-1001423507',
      'hostname': 'GTVOSS11',
      'status': 10,
      'site_location': 'IEAT01 Tipperary',
      'rack_number': 'VIRTUAL RACK',
      'rack_u_position': 0,
      'manufacturer': 'EMC',
      'model': 'VM',

    },
    {
      'bams_id': 'BAMS-1001368001',
      'hostname': 'None',
      'status': 10,
      'site_location': 'IEAT01 Tipperary',
      'rack_number': 'VIRTUAL RACK',
      'rack_u_position': 0,
      'manufacturer': 'HP',
      'model': 'HP BL460C GEN8',

    }
],
'full_name': 'Invalid (invalid)',
'email_address': 'Invalid'
},
{
  'booking_name': 'gtec/1101822/lmikdy/ls-rmea/oss11',
  'asset_count': 2,
  'pdg': 'Invalid',
  'user_area': 'Invalid',
  'deployment_number': 'Invalid',
  'spoc': 'invalid',
  'release': 'Invalid',
  'start_date': '2017-06-12 00:00:00',
  'end_date': '2017-06-16 00:00:00',
  'asset_info': [
    {
      'bams_id': 'BAMS-1001423507',
      'hostname': 'GTVOSS11',
      'status': 10,
      'site_location': 'IEAT01 Tipperary',
      'rack_number': 'VIRTUAL RACK',
      'rack_u_position': 0,
      'manufacturer': 'EMC',
      'model': 'VM',

    }
],
'full_name': 'Invalid (invalid)',
'email_address': 'Invalid'
}];

Here if I search for a string 'emc', it should return 2 objects. 1st object will have only one child as there is only one object has 'manufacturer' as 'emc'.

The output should be:

[
{
  'booking_name': 'gtec/1101822/lmikdy/ls-rmea/oss11',
  'asset_count': 2,
  'pdg': 'Invalid',
  'user_area': 'Invalid',
  'deployment_number': 'Invalid',
  'spoc': 'invalid',
  'release': 'Invalid',
  'start_date': '2017-06-12 00:00:00',
  'end_date': '2017-06-16 00:00:00',
  'asset_info': [
    {
      'bams_id': 'BAMS-1001423507',
      'hostname': 'GTVOSS11',
      'status': 10,
      'site_location': 'IEAT01 Tipperary',
      'rack_number': 'VIRTUAL RACK',
      'rack_u_position': 0,
      'manufacturer': 'EMC',
      'model': 'VM',

    }
],
'full_name': 'Invalid (invalid)',
'email_address': 'Invalid'
},
{
  'booking_name': 'gtec/1101822/lmikdy/ls-rmea/oss11',
  'asset_count': 2,
  'pdg': 'Invalid',
  'user_area': 'Invalid',
  'deployment_number': 'Invalid',
  'spoc': 'invalid',
  'release': 'Invalid',
  'start_date': '2017-06-12 00:00:00',
  'end_date': '2017-06-16 00:00:00',
  'asset_info': [
    {
      'bams_id': 'BAMS-1001423507',
      'hostname': 'GTVOSS11',
      'status': 10,
      'site_location': 'IEAT01 Tipperary',
      'rack_number': 'VIRTUAL RACK',
      'rack_u_position': 0,
      'manufacturer': 'EMC',
      'model': 'VM',

    }
],
'full_name': 'Invalid (invalid)',
'email_address': 'Invalid'
}];

How do I search for a string within an array of objects including nested object and return parent object if search string is found in child object ?

like image 497
Valay Avatar asked Jun 14 '17 16:06

Valay


1 Answers

You could use an iterative and recursive approach and return the result of the check and build new objects and arrays if the children matches the search value.

function getValue(item) {
    if (Array.isArray(item)) {
        return item.reduce(iterA, undefined);
    }
    if (item && typeof item === 'object') {
        return iterO(item);
    }
    if (typeof item !== 'object' && item.toString().toLowerCase().indexOf(search) !== -1) {
        return item;
    }
}

function iterO(o) {
    var temp = Object.keys(o).reduce(function (r, k) {
            var value = getValue(o[k]);
            if (value) {
                r = r || {};
                r[k] = value;
            }
            return r;
        }, undefined);

    if (temp) {
        Object.keys(o).forEach(function (k) {
            if (!(k in temp)) {
                temp[k] = o[k];
            }
        });
    }
    return temp;
}

function iterA(r, a) {
    var value = getValue(a);
    if (value) {
        r = r || [];
        r.push(value);
    }
    return r;
}

var data = [{ booking_name: "gtec/1101822/lmikdy/ls-rmea/oss11", asset_count: 2, pdg: "Invalid", user_area: "Invalid", deployment_number: "Invalid", spoc: "invalid", release: "Invalid", start_date: "2017-06-12 00:00:00", end_date: "2017-06-16 00:00:00", asset_info: [{ bams_id: "BAMS-1001423507", hostname: "GTVOSS11", status: 10, site_location: "IEAT01 Tipperary", rack_number: "VIRTUAL RACK", rack_u_position: 0, manufacturer: "EMC", model: "VM" }, { bams_id: "BAMS-1001368001", hostname: "None", status: 10, site_location: "IEAT01 Tipperary", rack_number: "VIRTUAL RACK", rack_u_position: 0, manufacturer: "HP", model: "HP BL460C GEN8" }], full_name: "Invalid (invalid)", email_address: "Invalid" }, { booking_name: "gtec/1101822/lmikdy/ls-rmea/oss11", asset_count: 2, pdg: "Invalid", user_area: "Invalid", deployment_number: "Invalid", spoc: "invalid", release: "Invalid", start_date: "2017-06-12 00:00:00", end_date: "2017-06-16 00:00:00", asset_info: [{ bams_id: "BAMS-1001423507", hostname: "GTVOSS11", status: 10, site_location: "IEAT01 Tipperary", rack_number: "VIRTUAL RACK", rack_u_position: 0, manufacturer: "EMC", model: "VM" }], full_name: "Invalid (invalid)", email_address: "Invalid" }],
    search = 'emc',
    result = data.reduce(iterA, undefined);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 113
Nina Scholz Avatar answered Sep 30 '22 06:09

Nina Scholz