Вот мой текущий массив выглядит так:
{ entity: 'A', type: 'request', requestUrl: 'val1' },
{ entity: 'A', type: 'response', responseUrl: 'val1' },
{ entity: 'B', type: 'request', requestUrl: 'val1' },
{ entity: 'B', type: 'response', responseUrl: 'val1' },
{ entity: 'C', type: 'request', requestUrl: 'val1' },
{ entity: 'C', type: 'response', responseUrl: 'val1' },
{ entity: 'D', type: 'request', requestUrl: 'val1' },
{ entity: 'D', type: 'response', responseUrl: 'val1' },
{ entity: 'DADA', type: '', responseUrl: 'val1' }
Каждая строка содержит атрибут с именем «entity», который имеет 2 строки: одна соответствует запросу, а другая соответствует ответу. Мне нужно объединить строки запроса и ответа, и иметь данные только в одну строку. (Атрибут type не имеет значения в объединенной строке, но должен иметь все остальные атрибуты). Таким образом, решение будет что-то вроде:
[{"entity":"A","type":"response","requestUrl":"val1","responseUrl":"val1"},
{"entity":"B","type":"response","requestUrl":"val1","responseUrl":"val1"},
{"entity":"C","type":"response","requestUrl":"val1","responseUrl":"val1"},
{"entity":"D","type":"response","requestUrl":"val1","responseUrl":"val1"}]
На данный момент вот что у меня есть: https://www.w3schools.com/code/tryit.asp?filename= FUHGQN2JON75
Не уверен, что это лучший способ сделать это. Приветствуются рекомендации по улучшению этого решения.
Спасибо.
7 ответов
Один из вариантов - использовать reduce
для группировки вашего массива в объект. Используйте entity
в качестве ключа. Используйте Object.assign
для преобразования объектов. Используйте Object.values
для преобразования объекта в массив.
var arr = [{"entity":"A","type":"request","requestUrl":"val1"},{"entity":"A","type":"response","responseUrl":"val1"},{"entity":"B","type":"request","requestUrl":"val1"},{"entity":"B","type":"response","responseUrl":"val1"},{"entity":"C","type":"request","requestUrl":"val1"},{"entity":"C","type":"response","responseUrl":"val1"},{"entity":"D","type":"request","requestUrl":"val1"},{"entity":"D","type":"response","responseUrl":"val1"},{"entity":"DADA","type":"","responseUrl":"val1"}];
var result = Object.values(arr.reduce((c, v) => {
c[v.entity] = Object.assign(c[v.entity] || {}, v);
return c;
}, {}));
console.log(result);
Вы можете использовать Map
и forEach()
:
let data = [{ entity: 'A', type: 'request', requestUrl: 'val1' },{ entity: 'A', type: 'response', responseUrl: 'val1' },{ entity: 'B', type: 'request', requestUrl: 'val1' },{ entity: 'B', type: 'response', responseUrl: 'val1' },{ entity: 'C', type: 'request', requestUrl: 'val1' },{ entity: 'C', type: 'response', responseUrl: 'val1' },{ entity: 'D', type: 'request', requestUrl: 'val1' },{ entity: 'D', type: 'response', responseUrl: 'val1' }];
let result = ((a, m) => {
a.forEach(o => {
m.set(o.entity, Object.assign((m.get(o.entity) || {}), o));
});
return [...m.values()];
})(data, new Map());
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Предполагая, что запрос и ответ являются последовательными, мы можем просто использовать операторы спреда для объединения
const data = [{ entity: 'A', type: 'request', requestUrl: 'val1' },
{ entity: 'A', type: 'response', responseUrl: 'val1' },
{ entity: 'B', type: 'request', requestUrl: 'val1' },
{ entity: 'B', type: 'response', responseUrl: 'val1' },
{ entity: 'C', type: 'request', requestUrl: 'val1' },
{ entity: 'C', type: 'response', responseUrl: 'val1' },
{ entity: 'D', type: 'request', requestUrl: 'val1' },
{ entity: 'D', type: 'response', responseUrl: 'val1' },
{ entity: 'DADA', type: '', responseUrl: 'val1' }]
const newData = data.reduce((acc, item, index) => {
if (index % 2 || !item.type) return acc;
acc.push({...item, ...data[index+1]})
return acc;
}, [])
console.log(newData)
Вы можете использовать этот ответ
var arr = [{ entity: 'A', type: 'request', requestUrl: 'val1' },
{ entity: 'A', type: 'response', responseUrl: 'val1' },
{ entity: 'B', type: 'request', requestUrl: 'val1' },
{ entity: 'B', type: 'response', responseUrl: 'val1' },
{ entity: 'C', type: 'request', requestUrl: 'val1' },
{ entity: 'C', type: 'response', responseUrl: 'val1' },
{ entity: 'D', type: 'request', requestUrl: 'val1' },
{ entity: 'D', type: 'response', responseUrl: 'val1' },
{ entity: 'DADA', type: '', responseUrl: 'val1' }];
var res = Array.from(
new Set(arr.filter(x => x.type).map(x=>x.entity))
)
.map(el => arr.find(obj => obj.entity === el))
console.log(res);//
/*
[{"entity":"A","type":"request","requestUrl":"val1"},
{"entity":"B","type":"request","requestUrl":"val1"},
{"entity":"C","type":"request","requestUrl":"val1"},
{"entity":"D","type":"request","requestUrl":"val1"}]
*/
Вы можете использовать для этого карту. отслеживает все ваши объекты сущности.
Позже вы можете преобразовать Map
обратно в массив.
const input = [
{ entity: 'A', type: 'request', requestUrl: 'val1' },
{ entity: 'A', type: 'response', responseUrl: 'val1' },
{ entity: 'B', type: 'request', requestUrl: 'val1' },
{ entity: 'B', type: 'response', responseUrl: 'val1' },
{ entity: 'C', type: 'request', requestUrl: 'val1' },
{ entity: 'C', type: 'response', responseUrl: 'val1' },
{ entity: 'D', type: 'request', requestUrl: 'val1' },
{ entity: 'D', type: 'response', responseUrl: 'val1' },
{ entity: 'DADA', type: '', responseUrl: 'val1' }
]
const entityMap = new Map();
input.forEach(element => {
let currentEntity = entityMap.get(element.entity) || {};
entityMap.set(element.entity, {
...currentEntity,
...element,
})
});
return Array.from(entityMap.values());
Вы можете использовать Array.reduce()
для этого:
var arr = [{ entity: 'A', type: 'request', requestUrl: 'val1' },
{ entity: 'A', type: 'response', responseUrl: 'val1' },
{ entity: 'B', type: 'request', requestUrl: 'val1' },
{ entity: 'B', type: 'response', responseUrl: 'val1' },
{ entity: 'C', type: 'request', requestUrl: 'val1' },
{ entity: 'C', type: 'response', responseUrl: 'val1' },
{ entity: 'D', type: 'request', requestUrl: 'val1' },
{ entity: 'D', type: 'response', responseUrl: 'val1' },
{ entity: 'DADA', type: '', responseUrl: 'val1' }];
var res = arr.reduce((acc, item)=>{
var existObj = acc.find(obj => obj.entity === item.entity);
if(!existObj){
acc.push(item);
} else {
existObj['responseUrl'] = item.responseUrl;
}
return acc;
}, []);
console.log(res);
Используйте Reduce для создания нового массива. Но в то же время выход должен быть проверен, если порядок объектов изменяется в массиве.
Давайте рассмотрим эти два объекта
{ entity: 'A', type: 'request', requestUrl: 'val1' },
{ entity: 'A', type: 'response', responseUrl: 'val1' }
Рассмотрим первый объект, и в этом объекте мы проверим, какой ключ присутствует во втором объекте, но теперь в первом объекте, затем добавим этот ключ в первый объект.
let orgArray = [{
entity: 'A',
type: 'response',
responseUrl: 'val1'
},
{
entity: 'A',
type: 'request',
requestUrl: 'val1'
},
{
entity: 'B',
type: 'request',
requestUrl: 'val1'
},
{
entity: 'B',
type: 'response',
responseUrl: 'val1'
},
{
entity: 'C',
type: 'request',
requestUrl: 'val1'
},
{
entity: 'C',
type: 'response',
responseUrl: 'val1'
},
{
entity: 'D',
type: 'request',
requestUrl: 'val1'
},
{
entity: 'D',
type: 'response',
responseUrl: 'val1'
},
{
entity: 'DADA',
type: '',
responseUrl: 'val1'
}
]
let newArray = orgArray.reduce(function(acc, curr) {
//get the index of the object where entity matches
let getIndexOfEntity = acc.findIndex(function(item) {
return item.entity === curr.entity
})
//if there is no such entity then it will give -1
if (getIndexOfEntity === -1) {
// in that case push the object
acc.push(curr)
} else {
// if entity exist
//now check which key is missing from the
// getting all the keys from both the object
let getAllKeyFromAccObj = Object.keys(acc[getIndexOfEntity]);
let getAllKeyFromCurrObj = Object.keys(curr)
// looping through the key and adding the missing key
getAllKeyFromCurrObj.forEach(function(item) {
if (getAllKeyFromAccObj.indexOf(item) === -1) {
acc[getIndexOfEntity][item] = curr[item]
}
})
}
return acc;
}, [])
console.log(newArray)
Похожие вопросы
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript / JS) и его различных диалектах / реализациях (кроме ActionScript). Включите все соответствующие теги в свой вопрос; например, [node.js], [jquery], [json] и т. д.