Обновите значение объекта с помощью javascript

Я хотел бы знать, как обновить массив списка объектов с помощью 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

Charlie 24.07.2019 06:02
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
134
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Переберите оба массива и измените, если они соответствуют вашему условию.

Обновлять: Посмотрите, как повторяются вложенные (один уровень глубины в вашем образце) объекты.

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 24.07.2019 06:30

@Senthil, проверьте еще раз, я обновил логику, чтобы значения ключей не были жестко запрограммированы. Но он будет вставлять новые поля из newObj, например, может вставлять "rate": 0.4 в объект в objList, у которого нет такого поля, это правильное поведение, которое вы хотите?

buræquete 24.07.2019 06:36

Приведенный ниже код будет динамически генерировать требуемый объект без какого-либо жесткого кодирования ключей или значений. Если вы хотите вернуть совершенно новый объект, возможно, вы можете изменить 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);

Другие вопросы по теме

Похожие вопросы

Как показать/скрыть div на основе выбранного значения Multiple в поле select2 jQuery
Как установить домашнюю страницу по умолчанию для нескольких файлов html в google appscript и опубликовать ее как WebApp
Получите уникальные даты из массива меток дат
У меня есть 2 элемента в div рядом, будет ли скрытие одного заставлять другой расширяться, чтобы заполнить пространство div, в котором они находятся?
Как сделать так, чтобы значение параметра выбора начиналось заново каждый раз при изменении его значения?
Как преобразовать первый индекс каждого массива в моем массиве массива из строки в int?
Как запустить задачу после уничтожения страницы в браузере?
Как мы можем понять и создать этот параметр внутри функции в javascript?
Преобразование даты и времени из Net в JavaScript не работает в IE
Как настроить таргетинг на поля ввода с помощью увеличенного идентификатора с помощью цикла For Loop