0

I have an array full of objects. Almost all objects have a different amount of keys value pairs. Some of these object have the same key value pairs.

Is there a nice way to remove all the sub-object-duplicates? (sub-object-duplicate = and object whose all key-value-pairs can be found in another object.)

In the example below e.g. it would remove the all middle objects and leave only the first and last one.

Many thanks in advance : )

The closest I got is using this from here, but I do not know how to add the if condition to only check for a property if it exists.

Unique by multiple properties ( id and name )

arr.filter((v,i,a)=>a.findIndex(t=>(t.id === v.id && t.name===v.name))===i)

Input

input = [
  {
    "key0": {
      "key1": "value1",
      "key2": "value1",
      "key3": "value1",
      "key4": "value1",
      "key5": "value1"
    }
  },
  {
    "key0": {
      "key1": "value1",
      "key3": "value1",
      "key5": "value1"
    }
  },
  {
    "key0": {
      "key1": "value1",
      "key2": "value1",
      "key3": "value1"
    }
  },
  {
    "key0": {
      "key1": "value1",
      "key2": "value1",
      "key5": "value1"
    }
  },
  {
    "key0": {
      "key1": "value1",
      "key2": "value2",
      "key3": "value2",
      "key4": "value2",
      "key5": "value2",
      "key6": "value2"
    },
  {
    "key0": {
      "key1": "value2",
      "key2": "value2",
      "key3": "value2",
      "key4": "value2",
      "key5": "value2",
      "key6": "value2"
    }
  }
]

Expected output

output = [
  {
    "key0": {
      "key1": "value1",
      "key2": "value1",
      "key3": "value1",
      "key4": "value1",
      "key5": "value1"
    }
  },
  {
    "key0": {
      "key1": "value2",
      "key2": "value2",
      "key3": "value2",
      "key4": "value2",
      "key5": "value2",
      "key6": "value2",
    }
  }
]

4
  • Correctly said.. @mplungjan Commented Oct 11, 2019 at 12:28
  • @mplungjan I tried to apply multiple stuff from here: stackoverflow.com/questions/2218999/… but I could only make it work, if I already know in advance, which keys an object has. : ( Commented Oct 11, 2019 at 12:59
  • @mplungjan I edited what I tried and which was the closest to what I want. 🤗 Commented Oct 11, 2019 at 13:03
  • solution almost done ;) Commented Oct 11, 2019 at 13:20

2 Answers 2

1

Here a very basic O(n2) complex solution:

var input = [
  {
    "key0": {
      "key1": "value1",
      "key2": "value1",
      "key3": "value1",
      "key4": "value1",
      "key5": "value1"
    }
  },
  {
    "key0": {
      "key1": "value1",
      "key3": "value1",
      "key5": "value1"
    }
  },
  {
    "key0": {
      "key1": "value1",
      "key2": "value1",
      "key3": "value1"
    }
  },
  {
    "key0": {
      "key1": "value1",
      "key2": "value1",
      "key5": "value1"
    }
  },
  {
    "key0": {
      "key1": "value1",
      "key2": "value2",
      "key3": "value2",
      "key4": "value2",
      "key5": "value2",
      "key6": "value2"
    }
  },
  {
    "key0": {
      "key1": "value2",
      "key2": "value2",
      "key3": "value2",
      "key4": "value2",
      "key5": "value2",
      "key6": "value2"
    }
  }
];

var isIncluded = function (a, b) {
	for (var key in a) {
  	if (!b[key] || b[key] !== a[key])
    	return false;
  }
  
  return true;
};


var output = [];

for (var i = 0; i < input.length; i++) {
	var toInclude = true;

  for (var j = 0; j < input.length; j++) {
  	if (j === i)
    	continue;
      
    if (isIncluded(input[i].key0, input[j].key0)) {
    	toInclude = false;
      break;
    }
  }
  
  if (!toInclude)
  	continue;
    
  output.push(input[i]);
}

console.log(output);
// document.write(JSON.stringify(output));

Note that the output gets 3 items since you may have made a mistake in one of your objects (mixing value1 and value2)

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

3 Comments

that doesn't provide the output @JilReg want
thanks @SimonDehaut I totally misread the initial question --'
@guillaumepotier Awesome, many many thanks! And yes, good catch, the result should contain 3 items! Many thanks!
0

Here's a solution to handle every array with elem looks like {key0:{}},... to your needed format. The eg below handle more than just value1 and value2 : whatever the value ! :)

let input = [ { "key0": { "key1": "value1", "key2": "value1", "key3": "value1", "key4": "value1", "key5": "value1" } }, { "key0": { "key1": "value1", "key3": "value1", "key5": "value1" } }, { "key0": { "key1": "value1", "key2": "value1", "key3": "value1" } }, { "key0": { "key1": "value1", "key2": "value1", "key5": "value1" } }, { "key0": { "key1": "value1", "key2": "value2", "key3": "value2", "key4": "value2", "key5": "value2", "key6": "value2" } }, { "key0": { "key1": "value2", "key2": "value2", "key3": "value2", "key4": "value2", "key5": "value2", "key6": "value2" } } ];

function format(input) {

  let output = input.map(el => Object.keys(el)).map(ell => ell[0]);

  //check if only 'key0' at root key
  let same = output.reduce((acc, curr) => acc == curr ? output[0] : false, output[0]) == output[0];
  if (!same) return;

  //list all possibles value (value1, value2, ...)
  let possibleVal = {};
  for (key in input) {
    for (sub in input[key]['key0']) {
      possibleVal[input[key]['key0'][sub]] = null;
    }
  }
  possibleVal = Object.keys(possibleVal); // make it an array

  // fill output with possible values as key and fill with all possible values
  output = {};
  possibleVal.map(el => output[el] = {});
  input.map(el => {
    Object.entries(el['key0']).map(ell => {
      let key = ell[0];
      let value = ell[1]
      output[value][key] = value;
    });
  });

  // format it correctly and return it
  return possibleVal.map(val => ({
    'key0': output[val]
  }));
}

let final = format(input);

console.log(JSON.stringify(final, null, 4));

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.