Я хотел бы знать, как обновить массив списка объектов с помощью javascript.
Как обновить objList с помощью newObjList, сопоставив id и name.
Если id и name совпадают, обновите объект вложенного массива objList.
var result = updateObj(objList, newObjList);
console.info(result);
function updateObj(list, newObjList){
var flatarr = list.map(e=>Object.entries(e).map(([k, val]) => val)).flat(3);
var filterService = newObjList.filter(e=>e.name= = "service");
//got stuck
}
var newObjList=[{
"id": "service",
"name": "bank",
"amount": 2000
},{
"id": "service",
"name": "credit",
"amount": 5000
}]
var objList=[
{
"btob": [{
"id": "service",
"name": "bank",
"amount": 1000
},{
"id": "fund",
"name": "bank",
"amount": 2000
},{
"id": "others",
"name": "bank",
"amount": 5000
}]
},{
"ctob":[{
"id": "service",
"name": "credit",
"amount": 1000,
"rate": 0.4
},{
"id": "fund",
"name": "credit",
"amount": 3000,
"rate": 0.2
},{
"id": "others",
"name": "credit",
"amount": 4000,
"rate": 0.6
}]
}]
}]
Ожидаемый результат:
var result=[
{
"btob": [{
"id": "service",
"name": "bank",
"amount": 2000
},{
"id": "fund",
"name": "bank",
"amount": 2000
},{
"id": "others",
"name": "bank",
"amount": 5000
}]
},{
"ctob":[{
"id": "service",
"name": "credit",
"amount": 5000,
"rate": 0.4
},{
"id": "fund",
"name": "credit",
"amount": 3000,
"rate": 0.2
},{
"id": "others",
"name": "credit",
"amount": 4000,
"rate": 0.6
}]
}]
}]



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


Переберите оба массива и измените, если они соответствуют вашему условию.
Обновлять: Посмотрите, как повторяются вложенные (один уровень глубины в вашем образце) объекты.
objList.forEach(items => {
items.forEach(item => {
newObj.some(entry => {
if (item.id === entry.id && item.name === entry.name) {
item.amount = entry amount;
return true; //Break the inner loop (if no duplicate entries expected in objList)
}
})
})
})
Обратите внимание, как напрямую ссылаются на исходные объекты массива.
Вы можете сделать следующее;
var flatList = objList.flatMap(obj => obj["btob"] || obj["ctob"]);
newObjList.forEach(newObj => flatList
.filter(obj => obj.id == newObj.id && obj.name == newObj.name)
.forEach(obj => Object.keys(newObj).forEach(key => obj[key] = newObj[key])));
Как вы можете видеть, код очень чистый и читаемый: сначала сглаживаются целевые objList, чтобы сделать их более доступными, затем просто повторяются newObjList, находят целевые объекты в сведенном списке и обновляют их. Эта логика обновления выполняется через Object.keys(), потому что OP хочет обновить объект без каких-либо жестко запрограммированных ключей в процессе.
Вы можете увидеть это в действии во фрагменте ниже;
var newObjList = [{
"id": "service",
"name": "bank",
"amount": 2000
}, {
"id": "service",
"name": "credit",
"amount": 5000
}];
var objList = [{
"btob": [{
"id": "service",
"name": "bank",
"amount": 1000
}, {
"id": "fund",
"name": "bank",
"amount": 2000
}, {
"id": "others",
"name": "bank",
"amount": 5000
}]
}, {
"ctob": [{
"id": "service",
"name": "credit",
"amount": 1000,
"rate": 0.4
}, {
"id": "fund",
"name": "credit",
"amount": 3000,
"rate": 0.2
}, {
"id": "others",
"name": "credit",
"amount": 4000,
"rate": 0.6
}]
}];
var flatList = objList.flatMap(obj => obj["btob"] || obj["ctob"]);
newObjList.forEach(newObj => flatList
.filter(obj => obj.id == newObj.id && obj.name == newObj.name)
.forEach(obj => Object.keys(newObj).forEach(key => obj[key] = newObj[key])));
console.info(objList);спасибо за помощь, но хочу вернуть объект без ключей жесткого кодирования ( obj.amount)
@Senthil, проверьте еще раз, я обновил логику, чтобы значения ключей не были жестко запрограммированы. Но он будет вставлять новые поля из newObj, например, может вставлять "rate": 0.4 в объект в objList, у которого нет такого поля, это правильное поведение, которое вы хотите?
Приведенный ниже код будет динамически генерировать требуемый объект без какого-либо жесткого кодирования ключей или значений. Если вы хотите вернуть совершенно новый объект, возможно, вы можете изменить return в функции map ниже на {... a} и {... childObj} в соответствии с ES6, чтобы получить новую копию внутренних объектов.
function updateObj(list, newobj){
const result = [];
objList.forEach(obj => {
Object.entries(obj).map(k => {
const newRootObj = {};
newRootObj[k[0]] = k[1].map(childObj => {
const a = newObj.find(nObj => nObj.id === childObj.id && nObj.name === childObj.name);
if (a) {
childObj.amount = a.amount;
}
return childObj;
});
result.push(newRootObj);
});
});
return result;
}
const newObj=[{
"id": "service",
"name": "bank",
"amount": 2000
},{
"id": "service",
"name": "credit",
"amount": 5000
}];
const objList=[
{
"btob": [{
"id": "service",
"name": "bank",
"amount": 1000
},{
"id": "fund",
"name": "bank",
"amount": 2000
},{
"id": "others",
"name": "bank",
"amount": 5000
}]
},{
"ctob":[{
"id": "service",
"name": "credit",
"amount": 1000,
"rate": 0.4
},{
"id": "fund",
"name": "credit",
"amount": 3000,
"rate": 0.2
},{
"id": "others",
"name": "credit",
"amount": 4000,
"rate": 0.6
}]
}];
const result = updateObj(objList, newObj);
console.info(result);Если вам нужно решение, которое вообще не зависит от жесткого кодирования, то есть без "btob" или "ctob", вы можете использовать .map() для циклического прохождения objList. Для каждого элемента в нем переберите все его пары ключ/значение и обновите совпадения, используя .find(). Это также оставляет ваш исходный объект в такт, а не переопределяет его.
Рассмотрим пример ниже, где я добавил дополнительный ключ, чтобы продемонстрировать расширяемость.
var newObj = [
{ "id": "service", "name": "bank", "amount": 2000 },
{ "id": "service", "name": "credit", "amount": 5000 },
{ "id": "test", "name": "test", "newKey": "Hello world!"}
];
var objList = [
{ "btob": [{ "id": "service", "name": "bank", "amount": 1000 },{ "id": "fund", "name": "bank", "amount": 2000 },{ "id": "others", "name": "bank", "amount": 5000 }] },
{ "ctob":[{ "id": "service", "name": "credit", "amount": 1000, "rate": 0.4 },{ "id": "fund", "name": "credit", "amount": 3000, "rate": 0.2 },{ "id": "others", "name": "credit", "amount": 4000, "rate": 0.6 }]},
{ "dtob": [{ "id": "test", "name": "test"}]}
];
let result = objList
.map(root => Object.keys(root)
.reduce((output,key) => (
{...output, [key]: root[key]
.flatMap(i => {
let replacement = newObj.find(f => i.id === f.id && i.name === f.name);
return replacement ? {...i, ...replacement} : i;
})
}
), {})
);
console.info(result);
Возможный дубликат Сравнение массивов объектов в JavaScript