Javascript - возвращает родительский элемент с единственным дочерним элементом, который соответствует заданной строке поиска в массиве объектов с вложенным объектом
Это следующий вопрос из моего предыдущего вопроса. Из полученного ответа я могу выполнить поиск внутри вложенного объекта в массиве объектов.
Скачайте скрипку, например.
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'
}];
Здесь, когда я ищу строку 'emc', функция возвращает два объекта, которые являются правильными. Но "emc" как "производитель" находится в дочернем объекте. И каждый дочерний объект не удовлетворяет этому условию. Результат, который я ищу, например, "emc", должен возвращать 2 родительских объекта. У первого родительского объекта должен быть только один ребенок (у другого ребенка есть "hp" в качестве производителя). Второй родительский объект должен иметь один дочерний элемент, соответствующий строке поиска.
Я попытался создать новый объект с результатом поиска, но не смог заставить его работать.
Как вернуть родительский объект только с дочерним элементом, который удовлетворяет заданной строке поиска?
Вот чат моего предыдущего вопроса, который поможет понять проблему и требования.
Ответы
Ответ 1
Вы можете использовать итеративный и рекурсивный подход и вернуть результат проверки и построить новые объекты и массивы, если они соответствуют значению поиска.
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; }
Ответ 2
Я не уверен, насколько глубоко ваш подход должен идти, но это должно сделать трюк
он сделает копию каждой строки, когда имеет дочерний элемент, и заменит набор только соответствующими значениями
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;
}));