Я бы использовал здесь комбинацию функций массива filter
и reduce
.
filter
удалит все элементы, где attributes.roles
не включает 'Tenant-Hyd'
.
reduce
затем сгладит массив groups
.
const arrayOfElements =
[
{
"username": "a",
"attributes":
{
roles:["Tenant-Hyd"],
groups:["InspectorIP", "InspectorFT"]
}
},
{
"username": "b",
"attributes":
{
roles:["Tenant-Pune"],
groups:["InspectorIP"]
}
},
{
"username": "c",
"attributes":
{
roles:["Tenant-Hyd"],
groups:["InspectorIP"]
}
}
];
const filtered = arrayOfElements.filter(x => x.attributes.roles.includes('Tenant-Hyd'));
console.log('filtered', filtered);
const flattened = filtered.reduce((arr, current) => {
// create a new object for each group with the current username
const groups = current.attributes.groups.map(group => ({
username: current.username,
groups: group
}));
// push the new objects into the array
arr.push(...groups);
// return the array to the next iteration
return arr;
}, []);
console.log('flattened', flattened);
Эта демонстрация устанавливает начальный массив, запускает filter
, а затем запускает reduce
. Я разделил шаги, чтобы вы могли видеть, что происходит на каждом этапе, но вы можете легко объединить их.
const result = arrayOfElements
.filter(x => x.attributes.roles.includes('Tenant-Hyd'))
.reduce((arr, current) => {
arr.push(...current.attributes.groups.map(group => ({
username: current.username,
groups: group
})));
return arr;
}, []);
Функция уменьшения
уменьшение Функция массива принимает обратный вызов и начальное значение. Я передаю пустой массив в качестве начального значения.
Это действительно более мощный map
. Исходный массив будет перебираться с обратным вызовом, вызываемым на каждой итерации. Значение, возвращаемое из обратного вызова, будет использовано в качестве аккумулятора на следующей итерации.
// declare the callback
const callback = (arr, current) => {
// arr is the initial value on the first loop
// and whatever we return from this callback on subsequent loops
// add our flattened items to the accumulated array
arr.push(...current.attributes.groups.map(group => ({
username: current.username,
groups: group
})));
// return the accumulated array to the next iteration
return arr;
};
// loop over the items in myArray, calling the callback for each item
// pass an empty array in as the accumulator
myArray.reduce(callback, []);
Более простая альтернатива будет такой:
const arr = [];
myArray.forEach(current => {
arr.push(...current.attributes.groups.map(group => ({
username: current.username,
groups: group
})));
});
Это легче понять, но это не так лаконично, как использование reduce
.