Извиняюсь, но я изучаю манипулирование массивами, пробовал кое-что, как и раньше, но просто не могу понять это. Я создаю приложение для реагирования и получил свои данные обратно из пользовательского интерфейса, но мне нужно переформатировать для API. Мой груз выглядит так...
0: {from: "U20", Id: "1922", to: "U21"}
1: {from: "U20", Id: "9338", to: "U21"}
2: {from: "U20", Id: "1927", to: "U21"}
3: {from: "U20", Id: "1730", to: "U21"}
Мне нужно создать группу для всех ids и опубликовать поля from и to.
{
"from": "U20",
"Ids": ["1922","9338","1927","1730"],
"to:": "U21"
}
У меня есть lodash в качестве вспомогательной библиотеки.
Нет, извините, забыл сказать, эти значения пока будут одинаковыми.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Для группировки по 2-м ключам можно сделать что-то подобное с помощью reduce. Создайте объект-аккумулятор с новым ключом, представляющим собой комбинацию from и to.
const input = [
{ from: "U20", Id: "1922", to: "U21" },
{ from: "U20", Id: "9338", to: "U21" },
{ from: "U20", Id: "1927", to: "U21" },
{ from: "U20", Id: "1730", to: "U21" }
];
const merged = input.reduce((acc, { from, to, Id }) => {
const key = `${from}-${to}`;
acc[key] = acc[key] || { from, to, Ids:[] };
acc[key]["Ids"].push(Id);
return acc;
}, {})
const output = Object.values(merged);
console.info(output);В вашем случае, если вы хотите просто первый объект, то output[0]
Если есть вероятность того, что в полях from и to будут разные значения, тогда ваш API должен измениться, чтобы принимать массив значений вместо одной строки. Однако, работая в предположении, что значения from и to всегда будут одинаковыми для каждого элемента в массиве...
const payload = [
{from: "U20", Id: "9338", to: "U21"},
{from: "U20", Id: "1927", to: "U21"},
{from: "U20", Id: "1730", to: "U21"},
];
const newValue = {
from: payload[0].from,
to: payload[0].to,
Ids: payload.map(item => item.Id)
};
Используйте уменьшение массива и в аккумуляторе передайте пустой объект. С помощью hasOwnProperty проверить, есть ли у объекта свойство from и если его значение совпадает, то в массив id протолкнуть значение
let data = [{
from: "U20",
Id: "1922",
to: "U21"
},
{
from: "U20",
Id: "9338",
to: "U21"
},
{
from: "U20",
Id: "1927",
to: "U21"
},
{
from: "U20",
Id: "1730",
to: "U21"
}
]
let newData = data.reduce(function(acc, curr) {
if (acc.hasOwnProperty('from') && acc.from === curr.from) {
acc.id.push(curr.Id)
} else {
acc = {
from: curr.from,
id: [curr.Id],
to: curr.to
}
}
return acc;
}, {});
console.info(newData)const a = [
{from: "U20", Id: "1922", to: "U21"},
{from: "U20", Id: "9338", to: "U21"},
{from: "U20", Id: "1927", to: "U21"},
{from: "U20", Id: "1730", to: "U21"},
{from: "U21", Id: "1745", to: "U22"},
{from: "U21", Id: "1755", to: "U22"},
]
const f = array => {
const result = []
// key-value storage
const variations = {}
array.forEach(item => {
// set storage key
const key = `${item.from}-${item.to}`;
// check if key exists
// if exists use it, if not - create empty array
variations[key] = variations[key] || []
// push item ids to storage
variations[key].push(item.Id)
})
Object.keys(variations).map(variation => {
// deconstruct storage key back to "from" and "to" values
const [from, to] = variation.split('-');
const obj = {};
// write "from" and "to" values
obj.from = from;
obj.to = to;
// add stored values
obj.ids = variations[variation]
// save
result.push(obj)
})
console.info(result)
}
f(a)С помощью следующего вы можете вести учет каждого списка Ids для каждой пары ключей from -> to.
const entries = [
{ from: 'U20', to: 'U21', Id: '1922' },
{ from: 'U20', to: 'U21', Id: '9338' },
{ from: 'U20', to: 'U21', Id: '1927' },
{ from: 'U20', to: 'U21', Id: '1730' },
]
const output = entries.reduce((map, {from, to, Id}) =>
{
if (!map[from])
{
map[from] = {}
}
if (!map[from][to])
{
map[from][to] = {from, to, Ids: []}
}
map[from][to].Ids.push(Id)
return map
}, {})
console.info(output)Попробуй это
var idArray = [];
var newObj = {};
var objArray = [{
"from": "U20",
"Id": "1922",
"to": "U21"
},
{
"from": "U20",
"Id": "9338",
"to": "U21"
},
{
"from": "U20",
"Id": "1927",
"to": "U21"
},
{
"from": "U20",
"Id": "1730",
"to": "U21"
}
]
for(var i=0; i<objArray.length; i++) {
for(var key in objArray[i]) {
if (key == 'Id') idArray.push(objArray[i][key])
}
}
newObj.from = objArray[0].from;
newObj.to = objArray[0].to;
newObj.Id = idArray;
console.info(JSON.stringify(newObj));
Немного другой подход, использующий Map и объединенный ключ для группировки с двумя значениями.
var data = [{ from: "U20", Id: "1922", to: "U21" }, { from: "U20", Id: "9338", to: "U21" }, { from: "U20", Id: "1927", to: "U21" }, { from: "U20", Id: "1730", to: "U21" }, { from: "U20", Id: "1730", to: "U22" }, { from: "U21", Id: "1730", to: "U22" }],
result = Array.from(data
.reduce(
(m, { from, to, Id }) =>
(k => m.set(k, { from, to, Ids: [...(m.has(k) ? m.get(k).Ids : []), Id] }))
([from, to].join('|')),
new Map
)
.values()
);
console.info(result);.as-console-wrapper { max-height: 100% !important; top: 0; }И еще одно решение:
const compare = (o1, o2) => o1.from === o2.from && o1.to === o2.to
return entries
.reduce((arr,entry) => !arr.find(a=>compare(a,entry)) ? arr.concat(entry) : arr, [])
.map( ({from,to})=> ({
from,
to,
ids: entries.filter(i=>compare(i,{from,to})).map(({id})=>id)
}))
Это решение использует Лодаш/fp для группировки всех объектов в массиве с помощью комбинации реквизитов from и to. Затем он отображает все группы обратно в массив, объединяя все объекты в каждой группе. Если объединенный реквизит — Id, он объединяет значения в массив.
const { flow, groupBy, props, join, map, mergeAllWith, cond, nthArg, eq, concat } = _;
const fn = flow(
groupBy(flow( // group by joining from and to as the key
props(['from', 'to']),
join('-')
)),
map(mergeAllWith(cond([[ // merge all objects in each group
flow(nthArg(2), eq('Id')), // if the prop name is Id, concat the values
concat
]])))
);
const input = [
{ from: "U20", Id: "1922", to: "U21" },
{ from: "U20", Id: "9338", to: "U21" },
{ from: "U20", Id: "1927", to: "U21" },
{ from: "U20", Id: "1730", to: "U21" }
];
const result = fn(input);
console.info(result);<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>Это просто. Ты можешь это сделать
const arr = [
{from: "U20", Id: "1922", to: "U21"},
{from: "U20", Id: "9338", to: "U21"},
{from: "U20", Id: "1927", to: "U21"},
{from: "U20", Id: "1730", to: "U21"}]
const newObject = {
from: arr[0].from,
Ids: arr.map(record => (record.Id)),
to: arr[0].to
}
могли бы вы иметь более одного значения
fromиto?