【问题标题】:math difference between 2 key-value objects js2个键值对象js之间的数学差异
【发布时间】:2019-08-11 08:43:11
【问题描述】:

如果我有 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)

【问题讨论】:

标签: javascript arrays object key


【解决方案1】:

您可以使用 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);

【讨论】:

  • 实际上不需要 forEach 键,当 for..in 无需访问给定对象之外的另一个对象时也可以正常工作
  • @mplungjan 是的,您是对的,但它们是两种做事方式,无论如何感谢您指出。 :)
【解决方案2】:

一个使用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);

【讨论】:

  • 当有一对一的结果时,我不明白reduce的选择
  • 预期结果应该是一个对象,而不是一个数组。如果输入是数组而输出是数组,则使用Array.map。如果输入是数组而输出是原始对象或(不可迭代)对象,请使用Array.reduce
  • 正确 - 错过了那个
  • 在我看来,我的仍然更容易掌握。首先保存 obj3 的创建被缺乏可读性所抵消stackoverflow.com/a/55264605/295783 - 仍然投赞成票
  • 可以说是的,但是正确比可读的 IMO 更重要。尤其是在回答问题时。此外,为了与 es5 兼容并记录在案,这个示例有点冗长。它可能是一个班轮。
【解决方案3】:

您可以采用适用于任何深度对象的迭代和递归方法。

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; }

【讨论】:

    【解决方案4】:

    这是我能创建的最简单的版本。

    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)

    【讨论】:

      【解决方案5】:

      这个怎么样

      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)
      

      【讨论】:

        【解决方案6】:

        您可以使用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);

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-01
          • 1970-01-01
          • 2013-09-18
          • 1970-01-01
          • 1970-01-01
          • 2014-07-21
          相关资源
          最近更新 更多