3
\$\begingroup\$

Given a table represented as a javascript array of objects, I would like create a list of unique values for a specific property.

var table = [
  {
    a:1,
    b:2
  },
  {
    a:2,
    b:3
  },
  {
    a:1,
    b:4
  }
];

var groups = _.groupBy(table, "a");
var array = [];
_.forOwn(groups, function(value, key){
  array.push(key);
});

console.log(array);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script>
Check your console

The problems with this code is that the groupBy keep track of the values, which I really don't care about, and I need to iterate over the entire list generated by group again so I can yank out the keys. It seems pretty inefficient to me and Im wondering if there is a smarter way to do this without reinventing the wheel (or perhaps if I should just bite the bullet and reinvent the wheel).

\$\endgroup\$
5
\$\begingroup\$

I know this is an old post but purely for those looking for ways to do this heres a way that I found works nicely with a single line

var table = [
  {
    a:1,
    b:2
  },
  {
    a:2,
    b:3
  },
  {
    a:1,
    b:4
  }
];

let result = [...new Set(table.map(item => item.a))];
document.write(JSON.stringify(result));

\$\endgroup\$
4
\$\begingroup\$

You can always use reduce. Lodash/underscore has a similar function, if compatibility is an important matter.

function getUniqueValuesOfKey(array, key){
  return array.reduce(function(carry, item){
    if(item[key] && !~carry.indexOf(item[key])) carry.push(item[key]);
    return carry;
  }, []);
}

var table = [{
  a:1,
  b:2
},{
  a:2,
  b:3
},{
  a:1,
  b:4
}];

// See snippet result
document.write(JSON.stringify(getUniqueValuesOfKey(table, 'a')));

\$\endgroup\$
3
\$\begingroup\$

You could also chain map and filter:

function unique(arr, prop) {
    return arr.map(function(e) { return e[prop]; }).filter(function(e,i,a){
        return i === a.indexOf(e);
    });
}

console.log(unique(table,'a')); //[1,2]
console.log(unique(table,'b')); //[2,3,4]
\$\endgroup\$
0
\$\begingroup\$

I'm not sure exactly what you're looking for, but here's an implementation in plain Javascript:

var table = [
  {
    a:1,
    b:2
  },
  {
    a:2,
    b:3
  },
  {
    a:1,
    b:4
  }
];

function getUniqueValues(array, key) {
    var result = new Set();
    array.forEach(function(item) {
        if (item.hasOwnProperty(key)) {
            result.add(item[key]);
        }
    });
    return result;
}

log('getUniqueValues(table, "a")');
getUniqueValues(table, "a").forEach(log);

log('getUniqueValues(table, "b")');
getUniqueValues(table, "b").forEach(log);

// utility function to display results in snippet
function log(value) {
    document.write(value + "<br>");
}

\$\endgroup\$
0
\$\begingroup\$

I found out there is an even simpler way to do this. The _.countBy() method does exactly what I want:

var table = [
  {
    a:1,
    b:2
  },
  {
    a:2,
    b:3
  },
  {
    a:1,
    b:4
  }
];


var array = _.countBy(table, function(t){
  return t.a;
});

console.log(array);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script>
Check your console

\$\endgroup\$
0
\$\begingroup\$

This might not be the best optimised code but definitely works!!

      let flag= 0;
      for(let i=0; i<Arr1.length; i++) {
        if(arr2[i]['prop']) {
           flag =0;
          for(let j=0; j<Arr1.length; j++){
            if(Arr1[j]['prop']=== arr2[i]['prop']){
              flag = 1;
              break;
            }
          }
          if(!flag) {
            Arr1.push(arr2[i]);
          }
        }
      }
\$\endgroup\$
  • \$\begingroup\$ Welcome to Code Review! You have presented an alternative solution, but haven't reviewed the code. Please edit it to explain your reasoning (how your solution works and how it improves upon the original) so that everyone can learn from your thought process. \$\endgroup\$ – Toby Speight Jul 17 '18 at 8:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.