математическая разница между двумя объектами значения ключа js - PullRequest
1 голос
/ 20 марта 2019

Если у меня есть 2 таких объекта:

var obj1 = {'a': [2, 3, 4], 'b': [5, 5, 5]}
var obj2 = {'a': [1, 1, 1], 'b': [2, 2, 2]}

Как я могу получить третий объект, подобный этому:

obj3 = {'a': [1, 2, 3], 'b': [3, 3, 3]} // difference between obj1 and obj2

Я пытался, но без результата:

var obj1 = {'a': [2, 3, 4], 'b': [5, 5, 5]}
var obj2 = {'a': [1, 1, 1], 'b': [2, 2, 2]}
var obj3 = Object.keys(obj1).filter(k => obj1[k] - obj2[k]);
console.log(obj3)

Ответы [ 6 ]

4 голосов
/ 20 марта 2019

Вы можете использовать вызовы методов Object.keys() и .forEach() для итерации по keys и выполнениянеобходимые расчеты.

Вот как должен быть ваш код:

var res = {};
Object.keys(obj1).forEach(function(k){
   res[k] = obj1[k].map((v,i) => v - obj2[k][i]);
});

Демо:

var obj1 = {'a': [2, 3, 4], 'b': [5, 5, 5]}
var obj2 = {'a': [1, 1, 1], 'b': [2, 2, 2]}
var res = {};
Object.keys(obj1).forEach(function(k){
   res[k] = obj1[k].map((v,i) => v - obj2[k][i]);
});

console.log(res);
3 голосов
/ 20 марта 2019

Пример использования Reduce и Map.

РЕДАКТИРОВАТЬ: я задокументировал некоторые шаги, чтобы помочь вам понять, что происходит.

/**
 * Returns the difference between each value in an array
 * positioned at each key listed in keys between objA and objB.
 *
 * @param {Object} objA - Every key should container an array of numbers to diff.
 * @param {Object} objB - Should match structure with objA.
 * @param {string[]} [keys] - Optional array with keys to diff, by default uses all the keys.
 * @returns {Object} - Object matching objA structure with diff'ed values in each key.
 */ 
function keyDiff(objA, objB, keys=Object.keys(objA)) {

  // Array.reduce "reduces" an array to a single object using using a function.
  // Function receives 2 arguments:
  // - Accumelated value (val, result of previous steps in every iteration).
  // - Current iterated value of array (key).
  return keys.reduce(function(acc, key) {
    
    // Array.map "maps" one array to another using a function.
    // Function receives 2 arguments:
    // - Current iterated value of array (v).
    // - Current iterator index (index).
    //
    // Current reducer value "key" is used to map objA values for key to
    // differnce with objB. This is done at the position specied by map index.
    // The result is set to the accumulater "acc" object which gets returned
    // at the end of the reducer.
    acc[key] = objA[key].map(function(v, index) {
      // Subtract objB value from objA value
      return v - objB[key][index];
    })
  
    // Return the new accumelator "acc" value.
    // The returned value of each step in the reducer is accumulator "acc".
    // This is the first value in the function passed as argument in the reducer.
    return acc;

  // By Default "null" is the inital accumulator value.
  // Since we need an object to start with we specify "{}" as the inital value.
  }, {});
}

var obj1 = {'a': [2, 3, 4], 'b': [5, 5, 5]}
var obj2 = {'a': [1, 1, 1], 'b': [2, 2, 2]}

var obj3 = keyDiff(obj1, obj2);
console.log(obj3);
2 голосов
/ 20 марта 2019

Вы можете использовать итеративный и рекурсивный подход, который работает для любых объектов глубины.

function delta(a, b) {
    return typeof a === 'object'
        ? Object.assign(
            Array.isArray(a) ? [] : {},
            ...Object.keys(a).map(k => ({ [k]: delta(a[k], b[k]) }))
        )
        : a - b;
}

var obj1 = { a: [2, 3, 4], b: [5, 5, 5] },
    obj2 = { a: [1, 1, 1], b: [2, 2, 2] },
    result = delta(obj1, obj2);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
2 голосов
/ 20 марта 2019

Это самая простая версия, которую я мог создать.

const obj1 = { 'a': [2, 3, 4],'b': [5, 5, 5]};
const obj2 = { 'a': [1, 1, 1],'b': [2, 2, 2]};
let   obj3 = {};

for (k in obj1) {
   obj3[k] = obj1[k].map((v, i) => v - obj2[k][i])
};
console.log(obj3)
1 голос
/ 20 марта 2019

Вы можете использовать Array.map() для создания многократно используемой функции вычитания массива.

После этого будет просто циклически проходить по клавишам объектов и выполнять эту функцию насоответствующие ключи.

var obj1 = {'a': [2, 3, 4], 'b': [5, 5, 5]}
var obj2 = {'a': [1, 1, 1], 'b': [2, 2, 2]}

const subtractArrays = (arr1,arr2) => arr1.map((val,idx) => val-arr2[idx]);

const result = Object.keys(obj1).reduce((out,key) => {
    out[key] = subtractArrays(obj1[key], obj2[key]);
    return out;
  }, {});
  
console.log(result);
1 голос
/ 20 марта 2019

Как насчет этого

var obj1 = {'a': [2, 3, 4], 'b': [5, 5, 5]}
var obj2 = {'a': [1, 1, 1], 'b': [2, 2, 2]}

var resultObj = {};

for(var i in obj1) {
  var firstObjArray = obj1[i];
  var secondObjArray = obj2[i];
  var differenceArray = firstObjArray.map(function(a, index) {
    return firstObjArray[index] - secondObjArray[index]
  });
  resultObj[i] = differenceArray;
}

console.log(resultObj)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...