3

I have this array of objects.

[
  {
    tier1: "Normal",
    tier2: "none",
    tier3: "none",
    tier4: "none",
    tier5: "none",
  },
  {
    tier1: "Urgent",
    tier2: "GCC & Labour",
    tier3: "new",
    tier4: "Cancellation",
    tier5: "Cancellation",
  },
  {
    tier1: "Urgent",
    tier2: "Foreigner",
    tier3: "renew",
    tier4: "Cancellation",
    tier5: "none",
  },
]

I need to get tier1, tier2, tier3 tier4 and tier5 values only single time.

So suppose in the above example tier1 has Normal one time and Urgent two times so it will be removed in the next element. tier5 has none in the first element so will be reomved from the last element as it already exists.

Output will be

[
  {
    tier1: "Normal",
    tier2: "none",
    tier3: "none",
    tier4: "none",
    tier5: "none",
  },
  {
    tier1: "Urgent",
    tier2: "GCC & Labour",
    tier3: "new",
    tier4: "Cancellation",
    tier5: "Cancellation",
  },
  { tier2: "Foreigner", tier3: "renew" },
]
0

4 Answers 4

1

If that's about re-mapping your source array with filtered copies of items-objects, based on previously seen key/value pairs, you may use Array.prototype.map() in combination with Object.assign() for re-mapping along with Object.keys() together with Array.prototype.reduce() for filtering:

const src = [{tier1:"Normal",tier2:"none",tier3:"none",tier4:"none",tier5:"none",},{tier1:"Urgent",tier2:"GCC & Labour",tier3:"new",tier4:"Cancellation",tier5:"Cancellation",},{tier1:"Urgent",tier2:"Foreigner",tier3:"renew",tier4:"Cancellation",tier5:"none",},],

simplify = (arr, hashMap = []) =>
  arr.map(o => Object.assign(
    {},
    ...Object.keys(o).reduce((r,key) => {
      const hash = key+'\ud8ff'+o[key]
      if(!hashMap.includes(hash)){
        r.push({[key]:o[key]})
        hashMap.push(hash)
      }
      return r
    }, [])
  ))

console.log(simplify(src))
.as-console-wrapper{min-height:100%;}

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

Comments

1

Something like this should yield the results you're looking for.

The runtime, by using a set to track duplicates, should be O(kN) where N is the number of entries in the array and k is the number of keys in each object (here it is 5), which is the tightest bound on this problem.

const data = [{
    tier1: "Normal",
    tier2: "none",
    tier3: "none",
    tier4: "none",
    tier5: "none",
  },
  {
    tier1: "Urgent",
    tier2: "GCC & Labour",
    tier3: "new",
    tier4: "Cancellation",
    tier5: "Cancellation",
  },
  {
    tier1: "Urgent",
    tier2: "Foreigner",
    tier3: "renew",
    tier4: "Cancellation",
    tier5: "none",
  },
]

const removeDuplicates = (arr) => {

  // retains a set of values for every key
  elementSet = {};
  return arr.map((elem) => {
    const newObj = {};

    // iterate over all the keys
    for (const key of Object.keys(elem)) {
      const value = elem[key];

      if (!(key in elementSet)) {
        // instantiate the set for the given key
        elementSet[key] = new Set();
      }

      if (!elementSet[key].has(value)) {
        // it hasn't been used before, so we can use it, but we'll add to the set for the future
        newObj[key] = elem[key];
        elementSet[key].add(elem[key]);
      }

    }
    return newObj;
  })
}


console.log(removeDuplicates(data))

Comments

1

Maintain Set of values for each key in a object. Use map and get the updated filtered object. (updated object will be keys which are not have already)

const all = {};

const updateObject = (obj) =>
  Object.fromEntries(
    Object.entries(obj).filter(([key, value]) => {
      if (!(key in all)) {
        all[key] = new Set();
      }
      const result = !all[key].has(value);
      all[key].add(value);
      return result;
    })
  );

const output = arr => arr.map(updateObject);

data = [
  {
    tier1: "Normal",
    tier2: "none",
    tier3: "none",
    tier4: "none",
    tier5: "none",
  },
  {
    tier1: "Urgent",
    tier2: "GCC & Labour",
    tier3: "new",
    tier4: "Cancellation",
    tier5: "Cancellation",
  },
  {
    tier1: "Urgent",
    tier2: "Foreigner",
    tier3: "renew",
    tier4: "Cancellation",
    tier5: "none",
  },
];



console.log(output(data));

Comments

-1

const data = [{
    tier1: "Normal",
    tier2: "none",
    tier3: "none",
    tier4: "none",
    tier5: "none",
  },
  {
    tier1: "Urgent",
    tier2: "GCC & Labour",
    tier3: "new",
    tier4: "Cancellation",
    tier5: "Cancellation",
  },
  {
    tier1: "Urgent",
    tier2: "Foreigner",
    tier3: "renew",
    tier4: "Cancellation",
    tier5: "none",
  },
]

let t1 = [],
  t2 = [],
  t3 = [],
  t4 = [],
  t5 = []

data.forEach(d => {
  if (!t1.includes(d.tier1)) t1.push(d.tier1)
  if (!t2.includes(d.tier2)) t2.push(d.tier2)
  if (!t3.includes(d.tier3)) t3.push(d.tier3)
  if (!t4.includes(d.tier4)) t4.push(d.tier4)
  if (!t5.includes(d.tier5)) t5.push(d.tier5)
})

let result = []
for (let i = 0; i < data.length; i++) {
  let object = {}
  if (t1[i]) object.tier1 = t1[i]
  if (t2[i]) object.tier2 = t2[i]
  if (t3[i]) object.tier3 = t3[i]
  if (t4[i]) object.tier4 = t4[i]
  if (t5[i]) object.tier5 = t5[i]
  result.push(object)
}

console.log(result)

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.