Home > Net >  Sort an object and remove duplicates
Sort an object and remove duplicates

Time:11-04

Given an object like this. How to write a function that will return the object with sorted keys and remove the duplicates from the first value e.g

const initialObj={
  "2": ["A", "B", "D", "A"],
  "1": ["A", "B", "C"],
 
}; 
const output = {
  "1": ["C"],
  "2": ["A", "B", "D"],
}
initial = {
  "1": ["C", "F", "G"],
  "2": ["A", "B", "C"],
  "3": ["A", "B", "D"],
}

output = {
  "1": ["F", "G"],
  "2": ["C"],
  "3": ["A", "B", "D"],
}

CodePudding user response:

const initialObj= {
    "1": ["C", "F", "G"],
    "2": ["A", "B", "C"],
    "3": ["A", "B", "D"],
  }  

function sortAndRemove(obj) {
    var keys = Object.keys(obj)
    keys.sort().reverse()
    seenBefore = new Set()
    answer = {}
    for (var key of keys) { 
        for (var value of obj[key]) {
            if (!seenBefore.has(value)) {
                answer[key] = [...(answer[key] || []), value]
                seenBefore.add(value)
            }
        }
    }
    return answer
}

console.log(sortAndRemove(initialObj))
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Considering the case that I got the algorithm you described, the following snippet would do the trick:

const initial1 = {
  "2": ["A", "B", "D", "A"],
  "1": ["A", "B", "C"],
};

const initial2 = {
  "1": ["C", "F", "G"],
  "2": ["A", "B", "C"],
  "3": ["A", "B", "D"],
}

// removing duplicates from array
const removeDuplicates = ({
  arr,
  toRemove
}) => {
  return arr.filter(char => !toRemove.includes(char))
}

// returns a sorted array!
const sortObjKeys = (obj) => {
  const entries = Object.entries(obj)
  const sorted = entries.sort(([key1], [key2]) => {
    return Number(key1) - Number(key2)
  })
  return sorted
}

// iterating over the sorted array (starting from the end)
const reducer = (sorted) => {
  const {
    ret
  } = sorted.reverse().reduce((a, [key, val]) => {
    const cleared = removeDuplicates({
      arr: [...new Set([...val])],
      toRemove: a.toRemove
    })
    a.ret = [
      [key, cleared], ...a.ret,
    ]
    a.toRemove = [...new Set([...a.toRemove, ...val])]
    return a
  }, {
    ret: [],
    toRemove: []
  })
  return ret
}

// putting it all together
const processSortedArr = (obj) => {
  const sorted = sortObjKeys(obj)
  const ret = reducer(sorted)
  return Object.fromEntries(ret)
}



console.log('output1', processSortedArr(initial1))
console.log('output2', processSortedArr(initial2))
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Here is a set of tools

Assuming the keys are strings and not numbers

If you want numerical sort, we need to cast to int

const deDupe = (arr1,arr2) => arr1.filter(val => !arr2.includes(val));


const sortDedupe = obj => {
  const newObj = {}
  const order = Object.keys(obj); // get the keys
  order.sort(); // sort them
  order.forEach(key => newObj[key] = obj[key]); // reorder the object
  for (let i=0;i<order.length-1;i  ) {
    newObj[order[i]] = deDupe(newObj[order[i]],newObj[order[i 1]]); //dedupe based on next
  }
  const last = order.pop()
  newObj[last] = [...new Set(newObj[last])]; // dedupe last
  return newObj
}




const initialObj={
  "2": ["A", "B", "D", "A"],
  "1": ["A", "B", "C"],
 
}; /*
const output = {
  "1": ["C"],
  "2": ["A", "B", "D"],
}*/
const initial = {
  "1": ["C", "F", "G"],
  "2": ["A", "B", "C"],
  "3": ["A", "B", "D"],
}
/*
output = {
  "1": ["F", "G"],
  "2": ["C"],
  "3": ["A", "B", "D"],
}*/

let output1 = sortDedupe(initialObj)
console.log(output1)
let output2 = sortDedupe(initial)
console.log(output2)
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related