1

I have below array of Objects-

var myarray = [ { "id": "", "AlphaNumber": "ADF12345", "terms": "1" }, { "id": "ABC12345", "AlphaNumber": "LL8888", "terms": "1" }, { "id": "", "AlphaNumber": "KK6666", "terms": "2" }, { "id": "", "AlphaNumber": "QQ1111", "terms": "3" }, { "id": "ABC12346", "AlphaNumber": "RR4444", "terms": "3" }, { "id": "", "AlphaNumber": "SS1111", "terms": "5" }, { "id": "ABC12347", "AlphaNumber": "ASQE223", "terms": "5" } ]

I want to check if multiple entries for the same terms are present in the array and remove the node that has id="" which means my output would have an entry having term and id not equals ''(empty string) for duplicate term entries.

Final value of myarray after the logic could be as below:

[{"id":"ABC12345","AlphaNumber":"LL8888","terms":"1"},{"id":"","AlphaNumber":"KK6666","terms":"2"},{"id":"ABC12346","AlphaNumber":"RR4444","terms":"3"},{"id":"ABC12347","AlphaNumber":"ASQE223","terms":"5"}]

4 Answers 4

2

Create a map object with terms as key. If the current terms doesn't exist in map or the already existing object doesn't have id, use the current object

const myarray = [ { "id": "", "AlphaNumber": "ADF12345", "terms": "1" }, { "id": "ABC12345", "AlphaNumber": "LL8888", "terms": "1" }, { "id": "", "AlphaNumber": "KK6666", "terms": "2" }, { "id": "", "AlphaNumber": "QQ1111", "terms": "3" }, { "id": "ABC12346", "AlphaNumber": "RR4444", "terms": "3" }, { "id": "", "AlphaNumber": "SS1111", "terms": "5" }, { "id": "ABC12347", "AlphaNumber": "ASQE223", "terms": "5" } ]

const map = {};

for (const o of myarray) {
  if (!map[o.terms]?.id)
    map[o.terms] = o
}

console.log( Object.values(map) )

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

Comments

1

Using Array#reduce and Map

  1. Group your data by terms in a Map.
  2. Find an item where id is not an empty string, if such an item does not exist pick the first item.

const 
  myarray = [ { "id": "", "AlphaNumber": "ADF12345", "terms": "1" }, { "id": "ABC12345", "AlphaNumber": "LL8888", "terms": "1" }, { "id": "", "AlphaNumber": "KK6666", "terms": "2" }, { "id": "", "AlphaNumber": "QQ1111", "terms": "3" }, { "id": "ABC12346", "AlphaNumber": "RR4444", "terms": "3" }, { "id": "", "AlphaNumber": "SS1111", "terms": "5" }, { "id": "ABC12347", "AlphaNumber": "ASQE223", "terms": "5" } ],
  
  res = Array.from(myarray.reduce(
    (m, o) => (m.has(o.terms) ? m.get(o.terms).push(o) : m.set(o.terms, [o]), m),
    new Map()
  ).values(), (v) => v.find(o => o.id !== "") || v[0]);

console.log(JSON.stringify(res));

Comments

1

You can do 2 steps:

  1. Group data by terms
  2. Filter data when data in a group greater than 1 item. Otherwise, keep the data in the group which have only one item.
if(values.length > 1) values = values.filter(r => r.id !== "");

const myarray=[{"id":"","AlphaNumber":"ADF12345","terms":"1"},{"id":"ABC12345","AlphaNumber":"LL8888","terms":"1"},{"id":"","AlphaNumber":"KK6666","terms":"2"},{"id":"","AlphaNumber":"QQ1111","terms":"3"},{"id":"ABC12346","AlphaNumber":"RR4444","terms":"3"},{"id":"","AlphaNumber":"SS1111","terms":"5"},{"id":"ABC12347","AlphaNumber":"ASQE223","terms":"5"}];
const result = [];

// Step 1
const groupingData = myarray.reduce((acc, curr) => {
  acc[curr.terms] ??= [];
  acc[curr.terms].push(curr);
  return acc;
}, {});

// Step 2
for(let [key, values] of Object.entries(groupingData)){
  if(values.length > 1) values = values.filter(r => r.id !== "");
  result.push(values);
}
console.log(result.flat());

4 Comments

Two problems with your current solution: 1) If there are 2 items where term is same but id is empty for both, then resultant would not have any objects with this term.
2) If there are 2 items where term is same and id is not empty for both, then resultant would have both objects with this term.
I don't think so. You can read the OP's requirement again and check my output answer
For OP's current input it works but for other inputs it might fail. Consider this input [{ id: "", AlphaNumber: "ADF12345", terms: "1" }, { id: "", AlphaNumber: "LL8888", terms: "1" }]
0

My suggestion:

const array = [{
    id: "",
    AlphaNumber: "ADF12345",
    terms: "1"
  }, {
    id: "ABC12345",
    AlphaNumber: "LL8888",
    terms: "1"
  }, {
    id: "",
    AlphaNumber: "KK6666",
    terms: "2"
  }, {
    id: "",
    AlphaNumber: "QQ1111",
    terms: "3"
  }, {
    id: "ABC12346",
    AlphaNumber: "RR4444",
    terms: "3"
  }, {
    id: "",
    AlphaNumber: "SS1111",
    terms: "5"
  }, {
    id: "ABC12347",
    AlphaNumber: "ASQE223",
    terms: "5"
  }],

  obj = {};

for (const o of array) obj[o.terms]?.id || (obj[o.terms] = o);

More about Optional chaining (?.)

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.