-2

I have two objects

object1 = {num: 0, num2: 0}
object2 = {num: 3, num2: 0}

I would like to compare both objects and get the highest one per object key, so my end results should be

result = {num: 3, num2: 0}

or if I had

object1 = {num: 0, num2: 0}
object2 = {num: 100, num2: 15}

I should get

result = {num: 100, num2: 15}

The highest math value per key.

The goal is to go through each object key comparing the two objects and pulling the highest numbered one. Per key also "num" is a var it can be anything and there could be more than two for example "num", "num1", "num2", "num3" and so forth.

Almog
  • 2,639
  • 6
  • 30
  • 59
  • 3
    Sounds interesting. What have you tried so far? Where did you get stuck? This sounds like a job for lodash with a custom merge (https://stackoverflow.com/questions/21120276/lodash-constructing-single-object-from-many-merging-overriding-properties). – jarmod Dec 16 '19 at 14:21
  • Can you please clarify the _"value per key"_ part. `{num: 10, num2: 0}, {num: 0, num2: 10}` should return `{ num: 10, num2: 10}` ? – Andreas Dec 16 '19 at 14:33

4 Answers4

0

Dynamic solution:

let ob1 = {a: 1, c:4};
let ob2 = {a: 2, b:3};
let ob3 = {b:5};

let lamba = function(...objects) {
    let result = {};
    objects.forEach(function (object) {
        for(let key in object) {
            if (object.hasOwnProperty(key) && typeof object[key] === "number") {
                result[key] = result[key] || 0;
                result[key] = (object[key] > result[key]) ? object[key] : result[key];
            }
        }
    });
    return result
};

let result = lamba(ob1, ob2, ob3);

console.log(result); // { a: 2, c: 4, b: 5 }
Mruf
  • 766
  • 7
  • 16
  • If for example, b is NaN I get 0 any ideas why? – Almog Dec 17 '19 at 13:15
  • I expected all obj values to be "normal" numbers. NaN is a special case `typeof NaN === "number"` and `NaN > 0 === false` so if you have a NaN it will be more or less casted to 0, because it is a Number but it is smaller than every value. If you don't want that, you would have to treat it as special case `if (object[key] === NaN && typeof result[key] === "undefined") {/* do something special with NaN*/}` – Mruf Dec 18 '19 at 07:59
0

You can use Object.keys() to firstly get the keys from one of your objects and then use .reduce() to build a new object from those keys. For each newly created key in the object, you can get the max of all the values for that key from the passed-in objects. This can be achieved by mapping each value to an array with .map(), and then getting the maximum number from that array. This approach will work for N objects which all have the same keys.

See example below:

const object1 = {num: 0, num2: 10, num3: 5};
const object2 = {num: 3, num2: 0, num3: 2};
const object3 = {num: 3, num2: NaN, num3: 2};

const getMaxObject = (...objects) => {
  const keys = objects.map(Object.keys).reduce((acc, arr) => acc.length > arr.length ? acc : arr, []);
  return keys.reduce(
    (acc, key) => ({...acc, [key]: Math.max(...objects.map(
      o => o[key] || 0
    ))}), {}
  );
}

console.log(getMaxObject(object1, object2, object3));
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
  • This works great, but if I have the following num2: NaN, or Null it ignores it how can I fix that? – Almog Dec 18 '19 at 09:44
  • @AlmogKoren Hi, I've updated my answer to use `.filter()` on the `.map()` results to filter out anything falsey, like `undefined`, `null`, etc. Does that fix your issue? – Nick Parsons Dec 18 '19 at 09:49
  • I don't want to filter it out, just ignore the value if you filter out then my final results will be missing for example num2 – Almog Dec 18 '19 at 10:06
  • @AlmogKoren I'm not sure I follow, above `num2` in the 3rd object is `NaN` and `num2` is present in the final object? – Nick Parsons Dec 18 '19 at 10:09
  • If I have the following objects, from the top the final results should be like so const object3 = {num: 3, num2: 10, num3: 5}; It just ignores the NaN and uses 10 as it's the highest – Almog Dec 18 '19 at 10:10
  • @AlmogKoren when I run the code snippet above on the three objects (with `num2` in the third being `NaN`) I get `{ "num": 3, "num2": 10, "num3": 5}` (which seems to be the result you're after), is that no what you get when you click "run code snippet"? – Nick Parsons Dec 18 '19 at 10:13
  • No, here is my real data First object {date_created: 1546293600000, num: 370} Second object date_created: 1546380000000, num: 370, num2: NaN} Results {date_created: 1546293600000, num: 370} Due not that it's rows so, for example, I have at the start {date_created: "2019-01-01", num: 100, num2: 300, category: "A"} – Almog Dec 18 '19 at 10:17
  • So one row can be NaN and another row can be 10, if it's NaN or undefied it should be like it's 0, I don't want to filter out key – Almog Dec 18 '19 at 10:19
  • @AlmogKoren ok, I see what the issue is, just to clarify, what do you expect the result to be for the two objects are `{date_created: 1546293600000, num: 370}` and `{date_created: 1546380000000, num: 370, num2: NaN}` ? – Nick Parsons Dec 18 '19 at 10:26
  • So for {date_created: 1546293600000, num: 370} {date_created: 1546380000000, num: 370, num2: NaN} {date_created: 1546380000000, num: 100, num2: 50} I would like to get the following {num: 370, num2: 50} – Almog Dec 18 '19 at 10:31
  • @AlmogKoren okay, I've updated my answer. The issue before was that the function was taking the keys from the first object, not the object with the largest amount of keys, the function does this now. If the function encounters `NaN` (or another falsey value, it uses `0`). Does this work for you? See [here](https://jsfiddle.net/yjveqt49/) for an example using the objects you mentioned in the comments – Nick Parsons Dec 18 '19 at 10:40
  • I just tested the there are two issues, I'm getting my first results are {date_created: NaN, num: 100, num2: 300, category: NaN} Which should be just {num: 100, num2: 300} Then I have an object were num2 is NaN and the results are {date_created: 1546293600000, num: 370, num2: 0} Which should be {num: 370, num2: 300} if the key vaule is NaN, undefined or just not a number it needs to ignore so when I get the max number it will always have the highest one – Almog Dec 18 '19 at 10:45
  • @AlmogKoren so you only want the keys which start with `num` ? Also can you give the objects where `num2` becomes `NaN`? – Nick Parsons Dec 18 '19 at 10:53
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/204484/discussion-between-nick-parsons-and-almog-koren). – Nick Parsons Dec 18 '19 at 10:54
-1

hope this helps

let high1 = 0, high2 = 0;
const object1 = {num: 0, num2: 0}
const object2 = {num: 3, num2: 0}

Object.keys(object1).forEach(item =>{
  if(object1[item] > high1){
    high2 = high1;
    high1 = object1[item]; 
  }
});

Object.keys(object2).forEach(item =>{
  if(object2[item] > high1){
    high2 = high1;
    high1 = object2[item]; 
  }
});

let result = {
  num : high1,
  num2 : high2,
}

console.log('result', result);
Summy
  • 443
  • 3
  • 5
  • 14
-1

If you choose to keep your numbers object inside an array.

let high1 = 0, high2 = 0;

const numbers = [
  {num: 0, num2: 0},
  {num: 3, num2: 0}
];

numbers.forEach( itemA =>{
  Object.keys(itemA).forEach(item =>{
    if(itemA[item] > high1){
      high2 = high1;
      high1 = itemA[item]; 
    }
  });
});

let result = {
  num : high1,
  num2 : high2,
}
Summy
  • 443
  • 3
  • 5
  • 14