简体   繁体   中英

javascript - return parent with only child that matches given search string in array of objects with nested object

This is a follow up question from my previous question . From the answer I've received, I am able to search within nested object in an array of objects.

Please find this fiddle for example .

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 when I search for a string 'emc', the function returns two objects which is correct. But 'emc' as 'manufacturer' is in child object. And every child object does not satisfies this condition. The result I am looking for, for example 'emc', it should return 2 parent objects. First parent object should have only one child (the other child has 'hp' as manufacturer). Second parent object should have one child as it matches the search string.

I tried to make a new object with search result but couldn't make it work.

How do I return parent object with only child that satisfies the given search string ?

Here is the chatlog on my previous question which can help to understand the problem and requirement.

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; } 

I am unsure how deep your approach need to go, but this should do the trick

it will make a copy of each row when the child item has it, and replace the set with the matching values only

 function filterSet(dataSet, matchFn) { return dataSet.reduce((current, row) => { if (typeof row === 'object') { for (let prop in row) { if (Array.isArray(row[prop])) { var set = filterSet(row[prop], matchFn); if (set && set.length > 0) { // copy the row, replace the array property with the results current.push( Object.assign({}, row, { [prop]: set } ) ); // since the full row is now in there // no need to check more break; } } else if (matchFn(row[prop])) { // copy not ref current.push( Object.assign( {}, row ) ); break; } } } return current; }, []); } 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' } ]; console.log(filterSet(data, (i) => { return i.toString().toLowerCase().indexOf('emc') >= 0; })); console.log(filterSet(data, (i) => { return i.toString().toLowerCase().indexOf('invalid') >= 0; })); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM