0

My json array with duplicates looks like:

var list = [
  {"id":"123","class": "Math K", "subject": "Counting & Cardinality"},
  {"id":"124","class": "Math K", "subject": "Counting & Cardinality"},
  {"id":"125","class": "Math K", "subject": "Counting & Cardinality"},
  {"id":"126","class": "Math K", "subject": "Counting & Cardinality"},
  {"id":"127","class": "Math K", "subject": "Geometry"},
  {"id":"128","class": "Math 1", "subject": "Counting & Cardinality"},
  {"id":"129","class": "Math 1", "subject": "Counting & Cardinality"},
  {"id":"120","class": "Math 1", "subject": "Orders of Operation"},
  {"id":"121","class": "Math 2", "subject": "Geometry"},
  {"id":"122","class": "Math 2", "subject": "Geometry"}
];

I need to remove duplicates with the same Class and Subject (e.g Math K and Counting & Cardinality or Math 2 and Geometry) but keep IDs for the first record, so it should look like:

var newList = [
  {"id":"123","class": "Math K", "subject": "Counting & Cardinality"},
  {"id":"127","class": "Math K", "subject": "Geometry"},
  {"id":"128","class": "Math 1", "subject": "Counting & Cardinality"},
  {"id":"120","class": "Math 1", "subject": "Orders of Operation"},
  {"id":"121","class": "Math 2", "subject": "Geometry"},
];

I have tried this code:

var newList = [];
for( var class in list ) {
  for( var subject in list[class] ) {
      outputList.push({ id: id, class: class, subject: subject });
  }
}
JSON.stringify( newList, null, 4 );

But it doesn't bring the results. I would really appreciate your help with tweaking my code. Thank you.

qqruza
  • 1,385
  • 4
  • 20
  • 41
  • 1
    JSON is a *textual notation* for data exchange. [(More here.)](http://stackoverflow.com/a/2904181/157247) If you're dealing with JavaScript source code, and not dealing with a *string*, you're not dealing with JSON. – T.J. Crowder Aug 17 '21 at 11:13
  • With all due respect, nothing in the code you've shown does anything that would even try to do what you've described (and should throw an error when run, as `id` is undeclared but you try to read its value). Your best bet here is to do your research, [search](/help/searching) for related topics on SO, and give it a go. ***If*** you get stuck and can't get unstuck after doing more research and searching, post a [mcve] of your attempt and say specifically where you're stuck. People will be glad to help. – T.J. Crowder Aug 17 '21 at 11:14
  • Does this answer your question? [Remove Duplicate objects from JSON Array](https://stackoverflow.com/questions/23507853/remove-duplicate-objects-from-json-array) – LeeLenalee Aug 17 '21 at 11:15
  • hi @LeeLenalee no, I used the example from that question, but it doesn't work with my IDs, which needs to be kept as the first one from each duplicate. – qqruza Aug 17 '21 at 11:17
  • @qqruza then update the example to use your IDs? At the moment that question and yours are _very_ similar – evolutionxbox Aug 17 '21 at 11:23
  • Hi @evolutionxbox that wasn't my question. I can update my array to stop getting people confused. – qqruza Aug 17 '21 at 11:24
  • Yes please do that. – evolutionxbox Aug 17 '21 at 11:25

3 Answers3

2

var list = [
  {"id":"123","class": "Math K", "subject": "Counting & Cardinality"},
  {"id":"124","class": "Math K", "subject": "Counting & Cardinality"},
  {"id":"125","class": "Math K", "subject": "Counting & Cardinality"},
  {"id":"126","class": "Math K", "subject": "Counting & Cardinality"},
  {"id":"127","class": "Math K", "subject": "Geometry"},
  {"id":"128","class": "Math 1", "subject": "Counting & Cardinality"},
  {"id":"129","class": "Math 1", "subject": "Counting & Cardinality"},
  {"id":"120","class": "Math 1", "subject": "Orders of Operation"},
  {"id":"121","class": "Math 2", "subject": "Geometry"},
  {"id":"122","class": "Math 2", "subject": "Geometry"}
];

var unique = [];
var result = [];
list.forEach(el => {
  // Let's create a string that is a combination of the class and subject
  var check = el.class + el.subject;
  // If its not in the unique array, let's add it
  if (unique.indexOf(check) < 0) {
    result.push(el);
    unique.push(check);
  }
})

console.log(result)
Wimanicesir
  • 4,606
  • 2
  • 11
  • 30
1

Another way to do it is to remove duplicates with a reduce().

The list.reduce() returns a object with keys of ${b.class}_${b.subject} and the values with the object looks like below:

{
  "Math K_Counting & Cardinality": {
    "id": "123",
    "class": "Math K",
    "subject": "Counting & Cardinality"
  },
  "Math K_Geometry": { "id": "127", "class": "Math K", "subject": "Geometry" },
  "Math 1_Counting & Cardinality": {
    "id": "128",
    "class": "Math 1",
    "subject": "Counting & Cardinality"
  },
  "Math 1_Orders of Operation": {
    "id": "120",
    "class": "Math 1",
    "subject": "Orders of Operation"
  },
  "Math 2_Geometry": { "id": "121", "class": "Math 2", "subject": "Geometry" }
}

Then extract the values of list.reduce() to get the result by Object.values()

const list = [
  { id: "123", class: "Math K", subject: "Counting & Cardinality" },
  { id: "124", class: "Math K", subject: "Counting & Cardinality" },
  { id: "125", class: "Math K", subject: "Counting & Cardinality" },
  { id: "126", class: "Math K", subject: "Counting & Cardinality" },
  { id: "127", class: "Math K", subject: "Geometry" },
  { id: "128", class: "Math 1", subject: "Counting & Cardinality" },
  { id: "129", class: "Math 1", subject: "Counting & Cardinality" },
  { id: "120", class: "Math 1", subject: "Orders of Operation" },
  { id: "121", class: "Math 2", subject: "Geometry" },
  { id: "122", class: "Math 2", subject: "Geometry" },
];

const output = Object.values(
  list.reduce((acc, b) => {
    if (!acc[`${b.class}_${b.subject}`]) acc[`${b.class}_${b.subject}`] = b;
    return acc;
  }, {})
);

console.log(output);
ikhvjs
  • 5,316
  • 2
  • 13
  • 36
1

Just for fun: a one-line-solution:

var list = [
  {"id":"123","class": "Math K", "subject": "Counting & Cardinality"},
  {"id":"124","class": "Math K", "subject": "Counting & Cardinality"},
  {"id":"125","class": "Math K", "subject": "Counting & Cardinality"},
  {"id":"126","class": "Math K", "subject": "Counting & Cardinality"},
  {"id":"127","class": "Math K", "subject": "Geometry"},
  {"id":"128","class": "Math 1", "subject": "Counting & Cardinality"},
  {"id":"129","class": "Math 1", "subject": "Counting & Cardinality"},
  {"id":"120","class": "Math 1", "subject": "Orders of Operation"},
  {"id":"121","class": "Math 2", "subject": "Geometry"},
  {"id":"122","class": "Math 2", "subject": "Geometry"}
];

// a.u: object with unique keys, a.c: array with the collection of first unique values:
res=list.reduce((a,el,k)=>(a.u[k=el.class+'_'+el.subject] || (a.u[k]=1) && a.c.push(el),a),{u:{},c:[]}).c;

console.log(res)

The script makes use of the fact that logical expressions are evaluated in a "lazy fashion", i. e. if the first operand of an or (||) expression evaluates to true then the second operand will never be evaluated.

Carsten Massmann
  • 26,510
  • 2
  • 22
  • 43