0

I have an object like below

var score = { 'A': 1, 'B': 2, 'C': 1 };

I want to create another object with key, value swapped and same valued keys grouped together, like below.

{ 1:['A', 'C'], 2: 'B' };

I dont want the single values, like 'B', inside an array. I want them alone. Please help.

Hi thanks for the answers. Finally to remove the array syntax if there is only one element i did the following.

$.each(obj, function(key, arr){
    if(arr.length == 1){
    obj[key] = arr[0]
  }
});
3
  • 4
    Have you tried anything? Where specifically are you stuck? You must have some thoughts about how to solve this problem... Commented Apr 28, 2017 at 15:37
  • Then why not "fix" this up after the fact? Iterate over the new object and change all properties with single element arrays with to the element itself. Commented Apr 28, 2017 at 15:57
  • Does this answer your question? Swap key with value in object Commented Jun 30, 2022 at 23:51

4 Answers 4

1

Possible solution, using Array#forEach.

var score = { 'A': 1, 'B': 2, 'C': 1 }, hash = {};
    Object.keys(score).forEach(v => (hash[score[v]] || (hash[score[v]] = [])).push(v));
    
    console.log(JSON.stringify(hash));

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

Comments

1

You can do this:

var score = { 'A': 1, 'B': 2, 'C': 1 };

var obj = {};
for(var i in score) {
   if(!obj[score[i]]) {
   obj[score[i]] = [i];
   } else {
	obj[score[i]].push(i);
   }
}

console.log(obj);

EDIT:

In the case when you don't want array for a single element, you can use this:

var score = { 'A': 1, 'B': 2, 'C': 1, 'D':1 };
    var obj = {};
    for (var i in score) {
        if (!obj[score[i]]) {
            obj[score[i]] = i;
        } else {
            var temp = obj[score[i]];
            if (Object.prototype.toString.call(temp) === "[object Array]") {
                obj[score[i]].push(i);
            } else {
                obj[score[i]] = [];
                obj[score[i]].push(temp);
                obj[score[i]].push(i);
            }
        }
    }
    
    console.log(obj);

1 Comment

Hi, Thanks..but I dont want an array if its a single valued key
0

var score = {
  'A': 1,
  'B': 2,
  'C': 1
};

var group = Object.keys(score).reduce(function(a, b) {
  var vKey = score[b];
  a[vKey] = a[vKey] || [];
  a[vKey].push(b);
  return a;
}, {});

console.log(group);

Comments

0

The following solution uses some more recent Javascript language features: object spread, array spread, computed property names, and the array concat method. Note that this method does not return an array for a single value as the question specifies.

const s = { 'A': 1, 'B': 2, 'C': 1 };

const o = Object.keys(s).reduce((a, k) =>
  ({...a, ...{[s[k]]: a[s[k]] ? [...a[s[k]]].concat(k) : k}}), {});

console.log(o);

The same solution is shown below, just fleshed out a little for more readability. It also includes an additional value ('D': 1) in the score which, if you pull apart the answer, shows the needs for the array spread. The comments show how the variable values change in each iteration through the loop.

const score = { 'A': 1, 'B': 2, 'C': 1, 'D': 1 };

const invertedScore = Object.keys(score).reduce((acc, key) => {
                          // iter'n#:   0     1      2            3
                          // key:      'A'   'B'    'C'          'D'
  const val = score[key]; // val:       1     2      1            1
  const prev = acc[val];  // prev:    undef undef   'A'       ['A','C']
  const chgd = prev ? [...prev].concat(key) : key;
                          // chgd:     'A'   'B'   ['A','C']  ['A','C','D']
  return ({...acc, ...{[val]: chgd}});
}, {});

console.log(invertedScore);

Comments

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.