1

I have this array of objects:

[{
  "Germany": "text",
  "Brazil": "50.00"
}, {
  "Germany": "1000.00",
  "Brazil": "1100.00"
}, {
  "Germany": "999999999",
  "Brazil": "9999999",
  "France": "12"
}]

I want to convert it to the following structure:

[{
  "name": "Germany",
  "value": 999999999
}, {
  "name": "Brazil",
  "value": 999999999
}, {
  "name": "France",
  "value": 12
}]

Where in the second object we use the higher value for each of the keys in the first object.

Edit: a value could also be text, like "Germany": "text" , in that case that value should be ignored. I added that case in the first object above.

4
  • 1
    What have you tried so far to solve this on your own? Commented Feb 9, 2021 at 11:23
  • "...we use the higher value for each of the keys in the first object" - Then why there's France in the end result? What if the value for Brazil in the last object would be 999? Would the value in the result be 1100.00 then? Commented Feb 9, 2021 at 11:24
  • 1
    This is a perfect task for any beginner to improve their javascript skills. Try splitting the problem up in different steps. 1. Save all the objects' keys and remove duplicates. 2. For each key, fetch all values that match that key, and save only the largest number. 3. Create a new list with the objects in key-value pairs formatted the way you want. Tip: you can use the Object class to get keys, values and key-value pairs (entries) for each object in the array. Tip 2: This isn't really a suitable question for stackoverflow. However, you could search for answers to step 1-3. Commented Feb 9, 2021 at 11:33
  • @Andreas Exactly Commented Feb 9, 2021 at 13:00

2 Answers 2

4

You can make use of reduce function to get your expected output. Inside reduce, you can take the Object.entries of the current object in order to group by the country name.

const arr = [{
  "Germany": "100.00",
  "Brazil": "50.00"
}, {
  "Germany": "1000.00",
  "Brazil": "1100.00"
}, {
  "Germany": "999999999",
  "Brazil": "9999999",
  "France": "12"
}];

const result = Object.values(arr.reduce((a,e)=>{
    Object.entries(e).forEach(([name, value])=>{
        a[name] ??= {name, value:0};
        a[name].value = a[name].value>value ? a[name].value : value
    });
    return a;
},{}));

console.log(result);

Sign up to request clarification or add additional context in comments.

Comments

3

You can use .reduce to iterate over the objects, and .forEach to iterate over each object entries:

const data = [
  { "Germany": "100.00", "Brazil": "50.00" }, 
  { "Germany": "1000.00", "Brazil": "1100.00" }, 
  { "Germany": "text", "Brazil": "9999999", "France": "12" }
];

const res = Object.values(data.reduce((acc,item) => {
  Object.entries(item).forEach(([name,value]) => {
    if(!isNaN(value)) {
      const prev = acc[name];
      if(!prev) acc[name] = { name,value } ;
      else if(prev.value < value) prev.value = value;
    }
  });
  return acc;
}, {}));

console.log(res);

4 Comments

What if I have text instead one of the numbers ? where should I check that it's a number only to compare ?
@stungbeet can you edit your question and expected result with this scenario?
@stungbeet I edited the answer to skip records with non-numeric values
I get Argument of type 'unknown' is not assignable to parameter of type 'number' edit: fixed by doing value as any

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.