1

I am trying to reformat my list of objects by grouping a certain key pair in javascript.

Data Format

[{
    "sccode": "sccode1",
    "val": "1ADA"
}, {
    "sccode": "sccode2",
    "val": "1ADB"
}, {
    "sccode": "sccode1",
    "val": "1ADC"
}]

Expected Result

[{
        "scCode": "sccode1",
        "valCodes": ["1ADA", "1ADC"]
    }, 
{
        "scCode": "sccode2",
        "valCodes": ["1ADB"]
    }

]

I believe I could loop through the array and match my keys, but is there a quick way to reformat this without having to explicitly loop through? I've tried using a reduce function below, but it gives undefined errors with find, which i think has something to do with my formatting.

Tried (?) Code

 const resp = data.reduce((acc, ele) => {
          const ant = acc.find(x => x.sccode === ele.sccode);
        }, []);

4 Answers 4

2

Would this do?

const src = [{"sccode":"sccode1","val":"1ADA"},{"sccode":"sccode2","val":"1ADB"},{"sccode":"sccode1","val":"1ADC"}],

    result = src.reduce((r,{sccode,val}) => {
      const match = r.find(({scCode}) => scCode == sccode)
      match ?
      match.valCodes.push(val) :
      r.push({scCode:sccode, valCodes: [val]})
      return r
    }, [])
    
console.log(result)
.as-console-wrapper{min-height:100%;}

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

1 Comment

so fresh and so clean clean
1

Try the following, I use a map to store a partial state to improve performances preventing to search sccode in an array for every initial object.

let partial = [{
  "sccode": "sccode1",
  "val": "1ADA"
}, {
  "sccode": "sccode2",
  "val": "1ADB"
}, {
  "sccode": "sccode1",
  "val": "1ADC"
}].reduce((map, obj) => {
  if (!map[obj.sccode]) {
    map[obj.sccode] = [obj.val];
  } else {
    map[obj.sccode].push(obj.val);
  }
  return map;
}, {})

Object.keys(partial).map(sccode => ({
  sccode, valCodes: partial[sccode]
}));

5 Comments

Even though I agree that, in general, O(n) -time algorithms (your solution) are naturally faster than O(n²) (mine). But it is still questionable at which point (source array size and group key sccode variation) more optimal algorithm will outperform heavier (involving type switching and Object.keys() extraction) implementation.
Unfortunatelly, I couldn't benchmark that as your code fails with error even when copy pasted as is into the console.
@YevgenGorbunkov look at this stackoverflow.com/questions/17295056/…
as being said, I have no doubts that 2 passes over the array theoretically are faster than single pass with nested look ups (and I don't need to scroll the thread 10 miles long to get convinced). However, it depends on source data structure and typical size whether you will see the performance gain that outweighs slow Object.keyss() mapping and data types switching (not to mention greater code verbosity). If you would manage to post working code at the very beginning I would do my benchmarking and, furthermore, gladly upvoted your answer if it is really blazing fast.
@YevgenGorbunkov I agree with you, it depends on how much data has to be processed and how many different sccodes there are. Code is working, was missing the return in reduce function.
0

try loaddash/groupby

let groupByResult = groupBy(data, function (n) {
          return n.sccode
        });

Comments

0

Check this code:

    array.reduce(function(res, value){
        if(!res[value.sccode]) {
            res[value.sccode] = value; 
            res[value.sccode]['valCodes'] = []
            result.push(res[value.sccode]);
        }
        res[value.sccode]['valCodes'].push(value.val); 
        return res; 
    } ,{}); 

I tested here and it works fine!

1 Comment

Except for it fails with an error ``result` is not defined' and returns an object whereas array is required

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.