Home > other >  Performing operations across typescript objects by key
Performing operations across typescript objects by key

Time:02-14

In typescript, I have two objects with matching keys, and the values are of type number[][], for example:

const A = {
    "X": [ [100, 20], [200, 35], [300, 30] ],
    "Y": [ [400, 20], [500, 15], [600, 25] ],
    "Z": [ [700, 30], [800, 35], [900, 40] ]
}

const B = {
    "X": [ [100, 2], [200, 3], [300, 2] ],
    "Y": [ [400, 1], [500, 3], [600, 2] ],
    "Z": [ [700, 3], [800, 3], [900, 2], [1000, 4 ]
}

I would like a function which is able to match the keys in each of the objects, merge the values based on the first entry in the inner arrays, and then finally perform an operation on the 2nd entry in the arrays, for example multiply the values.

The desired output would be a third object in the same format as A and B, like so:

C = A * B

const C = {
    "X": [ [100, 40], [200, 105], [300, 60] ],
    "Y": [ [400, 20], [500, 45], [600, 50] ],
    "Z": [ [700, 90], [800, 105], [900, 160] ]
}

Note that since the value of "1000" only appears in B, it is not included in C

This is my attempt so far:

C =  Object.keys(A).reduce((o,key)  => ({ ...o, [key]: A.key[1]*B.key[1]}), {})

However, I am getting the error message "Cannot read properties of undefined (reading '1')"

Any help here would be greatly appreciated!

CodePudding user response:

You can try this, hope it will help

const A = {
  X: [
    [100, 20],
    [200, 35],
    [300, 30],
  ],
  Y: [
    [400, 20],
    [500, 15],
    [600, 25],
  ],
  Z: [
    [700, 30],
    [800, 35],
    [900, 40],
  ],
};

const B = {
  X: [
    [100, 2],
    [200, 3],
    [300, 2],
  ],
  Y: [
    [400, 1],
    [500, 3],
    [600, 2],
  ],
  Z: [
    [700, 3],
    [800, 3],
    [900, 2],
    [1000, 4],
  ],
};

const operation = (a, b) => a * b;

const mergeArrays = (arr1, arr2) => {
  const newArr = [];
  arr1.forEach(([key1, val1]) => {
    const val2 = arr2.find(([key2]) => key2 === key1)?.[1];
    if (val2) {
      // if item with the same key exeist in second array
      // pushing pair to new array
      newArr.push([key1, operation(val1, val2)]);
    }
  });
  return newArr;
};

const mergeObjects = (obj1, obj2) => {
  const newObj = {};
  for (const key in obj1) {
    // I assume you want intersection of object keys too
    if (key in obj2) {
      newObj[key] = mergeArrays(obj1[key], obj2[key]);
    }
  }
  return newObj;
};

console.log(mergeObjects(A, B));
.as-console-wrapper{top:0;max-height:100%!important}

CodePudding user response:

typescript

type Pair<K, V> = [K, V];
type IndexableOf<T> = { [key: string]: T };

function calculate_product(a: IndexableOf<Pair<number, number>[]>, b: IndexableOf<Pair<number, number>[]>): IndexableOf<Pair<number, number>[]> {

  const product: IndexableOf<Pair<number, number>[]> = {};

  Object.keys(a).forEach(key => {
    product[key] =
      pairise(a[key], b[key])
        .map(pair => multiply_pairized(pair))
  });
  return product;

  function multiply_pairs(pair1: Pair<number, number>, pair2: Pair<number, number>): Pair<number, number> {
    return [pair1[0], pair1[1] * (isNaN(pair2[1]) ? 1 : pair2[1])];
  }

  function pairise(arrayOfPairs1: Pair<number, number>[], arrayOfPairs2: Pair<number, number>[]): Pair<Pair<number, number>, Pair<number, number>>[] {
    return arrayOfPairs1.map((pair: Pair<number, number>, index: number) => [pair, arrayOfPairs2[index] || []]);
  }

  function multiply_pairized(pair: Pair<Pair<number, number>, Pair<number, number>>) {
    return multiply_pairs(pair[0], pair[1]);
  }
}

const a: IndexableOf<Pair<number, number>[]> = {
  "X": [[100, 20], [200, 35], [300, 30]],
  "Y": [[400, 20], [500, 15], [600, 25]],
  "Z": [[700, 30], [800, 35], [900, 40]]
};

const b: IndexableOf<Pair<number, number>[]> = {
  "X": [[100, 2], [200, 3], [300, 2]],
  "Y": [[400, 1], [500, 3], [600, 2]],
  "Z": [[700, 3], [800, 3], [900, 2], [1000, 4]]
};

// console.log(calculate_product(a, a));
// console.log(calculate_product(b, b));
console.log(calculate_product(a, b));

Illustration: Javascript Code

function calculate_product(a, b) {
  const product = {};
  Object.keys(a).forEach(key => {
    product[key] =
      pairise(a[key], b[key])
      .map(pair => multiply_pairized(pair));
  });
  return product;

  function multiply_pairs(pair1, pair2) {
    return [pair1[0], pair1[1] * (isNaN(pair2[1]) ? 1 : pair2[1])];
  }

  function pairise(arrayOfPairs1, arrayOfPairs2) {
    return arrayOfPairs1.map((pair, index) => [pair, arrayOfPairs2[index] || []]);
  }

  function multiply_pairized(pair) {
    return multiply_pairs(pair[0], pair[1]);
  }
}

const a = {
  "X": [
    [100, 20],
    [200, 35],
    [300, 30]
  ],
  "Y": [
    [400, 20],
    [500, 15],
    [600, 25]
  ],
  "Z": [
    [700, 30],
    [800, 35],
    [900, 40]
  ]
};

const b = {
  "X": [
    [100, 2],
    [200, 3],
    [300, 2]
  ],
  "Y": [
    [400, 1],
    [500, 3],
    [600, 2]
  ],
  "Z": [
    [700, 3],
    [800, 3],
    [900, 2],
    [1000, 4]
  ]
};

// console.log(calculate_product(a, a));
// console.log(calculate_product(b, b));
console.log(calculate_product(a, b));



WYSIWYG => WHAT YOU SHOW IS WHAT YOU GET

  • Related