Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reduce duplicate in a javascript object

I've got an object like:

{
    a : 'foo',
    b : 'bar',
    c : 'foo',
    d : 'baz',
    e : 'bar'
}

I want to reduce the duplicates like:

{
    ac : 'foo',
    be : 'bar',
    d : 'baz'
}

What's a good way to do that?

A few caveats:

  • There will only ever be a small number of pairs. (Currently there are 7; I could imagine it going up to, say, 20.)
  • The initial property names will only ever be a single character, like in the example
  • The values could potentially run to several hundred characters.
  • both speed and code-length are highly important, but given the small number of rows, code clarity is probably still most important.
like image 429
sprugman Avatar asked Oct 25 '22 22:10

sprugman


2 Answers

var Reduce = function(obj)
{
  var temp = {};
  var val = "";

  for (var prop in obj)
  {
    val = obj[prop];
    if (temp[val])
      temp[val] = temp[val] + prop.toString();
    else
      temp[val] = prop.toString();
  }

  var temp2 = {};

  for (var prop in temp)
  {
    val = temp[prop];
    temp2[val] = prop.toString();
  }

  return temp2;
};

Use as:

var obj = {
  a :"foo",
  b : "bar",
  c : "foo",
  d : "bar", 
  e : "bar"
};

var ob2 = Reduce(obj);
like image 86
Matthew Abbott Avatar answered Oct 28 '22 04:10

Matthew Abbott


This is the shortest I could get it:

var obj, newObj = {}; // obj is your original
for (var i in obj) {
    if (!obj.hasOwnProperty(i)) continue;
    for (var j in newObj) {
        if (newObj.hasOwnProperty(j) && newObj[j] === obj[i]) break;
        j = "";
    }
    newObj[i + j] = obj[i];
    j && delete newObj[j];
}

Explanation:

  • It loops through each item in the original object, obj, and produces a new object, newObj.
  • For each item in the original, it searches the half-produced newObj for the same value. - The result is j, either the name of the property if found, or an empty string if not.
  • In either case, the new object needs a property of the same name as the current property in the original object, plus this value of j.
  • It also deletes the found property in newObj if there was one, to prevent duplicates being constructed.

Admittedly, setting j = "" within the loop is inefficient. This can easily be replaced with a second variable set to "" initially, and j only if a match is found. I decided to go for simplicity though.

like image 28
David Tang Avatar answered Oct 28 '22 05:10

David Tang