Home > Software engineering >  There is 2 array of object with same id, but one object property is true and other property is false
There is 2 array of object with same id, but one object property is true and other property is false

Time:05-12

I have array of object, there is 2 array of object with same id, but one object property is true and other property is false, how to remove both if property is false.

[{id: 'a660f87e-476d-493b-a220-31aff8cf764c', selected: true}
{id: '1e8284a5-6ba3-48c0-b8ac-f6ffae55b44e', selected: true}
{id: 'a660f87e-476d-493b-a220-31aff8cf764c', selected: false}]

So this is the array but 2 object have id "a660f87e-476d-493b-a220-31aff8cf764c" and one has selected property false and another one true, so if there is false I want object with that id should remove so I need final result like this.

 [{id: '1e8284a5-6ba3-48c0-b8ac-f6ffae55b44e', selected: true}]

If array is like this

  [{id: 'a660f87e-476d-493b-a220-31aff8cf764c', selected: true}
    {id: '1e8284a5-6ba3-48c0-b8ac-f6ffae55b44e', selected: true}
    {id: 'a660f87e-476d-493b-a220-31aff8cf764c', selected: true}]

I want result as

    [{id: 'a660f87e-476d-493b-a220-31aff8cf764c', selected: true}
    {id: '1e8284a5-6ba3-48c0-b8ac-f6ffae55b44e', selected: true}
   ]`

Can anyone suggest solution .

Thanks

CodePudding user response:

First step: You want to remove exact duplicates from your array. To do that you can do the following (assuming the array holding your data is called dataStore and the objects saved in it are called dataObject)

DataObject[] dataStore = { ... };
Set<String> dataStoreSet = new HashSet<DataObject>();
List<DataObject> dataStoreList = new ArrayList<DataObject>();
for(DataObject object: dataStore) {
   if(dataStoreSet.add(dataStore[object])) {
     dataStoreList.add(object);
   }
}
DataObject[] uniqueObjects = dataStoreList.toArray(new DataObject[dataStoreList.size()]);

Second step: You want to remove all occurences of object if one has the selected attribute on true

List<DataObject> test = Arrays.stream(objects).toList();
HashMap<String, DataObject> hashMap = new HashMap<>();
for(DataObject object : test) {
    if(hashMap.get(object.id) != null) {
        hashMap.remove(object.id);
    } else {
        hashMap.put(object.id, object);
    }
}
DataObject [] cleanedArray = (DataObject[]) hashMap.values().toArray();

We use the fact, that there can't be any duplicates anymore, so if there is the same id inside the HashMap, it needs to have a different other attribute than ID. Please note that you might have to implement an equalsmethod on your DataObject class and this suffices only for this object structure. If you have more than these two attributs, you would need to check the different states of the selected variable inside the if clause.

CodePudding user response:

Without using any 3rd party library, what I did was to build a dictionary where each key is your id and each value is {count: <the number of ids>, isSelected: <are all ids selected>}.

Then when I iterate the array I have 3 cases -

  1. only single id - stay in the result.
  2. more than 1 id but is selected is false - remove all.
  3. more than 1 id but is selected is true - remove until we will have count === 1, which will fall to the first case.

function extract(array) {
  let ids = {};
  array.forEach(item => {
    if (!ids[item.id])
      ids[item.id] = {
        count: 1,
        isSelected: item.selected
      };
    else {
      ids[item.id].count  ;
      ids[item.id].isSelected = ids[item.id].isSelected && item.selected;
    }
  });

  return array.filter(item => {
    if (ids[item.id].count === 1) return true;
    else if (!ids[item.id].isSelected) return false;
    else ids[item.id].count--;
    return false;
  })
}

const arr1 = [{
    id: 'a660f87e-476d-493b-a220-31aff8cf764c',
    selected: true
  },
  {
    id: '1e8284a5-6ba3-48c0-b8ac-f6ffae55b44e',
    selected: true
  },
  {
    id: 'a660f87e-476d-493b-a220-31aff8cf764c',
    selected: false
  }
];

const arr2 = [{
    id: 'a660f87e-476d-493b-a220-31aff8cf764c',
    selected: true
  },
  {
    id: '1e8284a5-6ba3-48c0-b8ac-f6ffae55b44e',
    selected: true
  },
  {
    id: 'a660f87e-476d-493b-a220-31aff8cf764c',
    selected: true
  }
];


console.log(extract(arr1));
console.log(extract(arr2));

CodePudding user response:

All you need is Array.reduce with Array.filter

If you want to select only those object whose selected property is true, irrespective of what value id holds then can try below snippet.

let arr = [
    {id: 'a660f87e-476d-493b-a220-31aff8cf764c', selected: true},
    {id: '1e8284a5-6ba3-48c0-b8ac-f6ffae55b44e', selected: true},
    {id: '1e8284a5-6ba3-48c0-b8ac-f6ffae55b44f', selected: false},
    {id: '1e8284a5-6ba3-48c0-b8ac-f6ffae55b44e', selected: false},
    {id: 'a660f87e-476d-493b-a220-31aff8cf764c', selected: true}
]


arr = Object.values(arr.reduce( (a, b) => {
    a[b.id] = a[b.id] ? a[b.id] : b ;
    return a;
}, {})).filter(a => a.selected === true)

console.log(arr);

You can provide you check just like if condition to filter

CodePudding user response:

So two action items in your questions.

  1. Get the items only if selected is true
  2. If the selected id already available in new array then not required to include again(Like you want unique array).

you can achieve it like below.

let tmp = [{id: '1', selected: true},
{id: '2', selected: true},
{id: '1', selected: true}];

var newArr = [];
var tmp1 = tmp.map((itm) => {
  var t = newArr.map(a => a.id);
    if(t.indexOf(itm.id) == -1 && itm.selected) {
    newArr.push(itm);
  }
});
console.log(newArr);

CodePudding user response:

So basically you want to remove object with selected: false from the array, right?

Maybe you can use a loop to remove the object with selected: false.

let _array = [{
        id: 'a660f87e-476d-493b-a220-31aff8cf764c',
        selected: true
    },
    {
        id: '1e8284a5-6ba3-48c0-b8ac-f6ffae55b44e',
        selected: true
    },
    {
        id: 'a660f87e-476d-493b-a220-31aff8cf764c',
        selected: false
    }
];
let temp_array = [];
_array.forEach((object, index) => {
    if (object.selected == false && hasDuplicate(object.id) == true) {
        _array.splice(index, 1);
    }
});

function hasDuplicate(id) {
    // function for finding if the element has a duplicate.
    _array.forEach(object => {
        temp_array.push(object.id)
    }); // A temporary array for storing all the ids.
    var indexes = [],
        i = -1;
    while ((i = temp_array.indexOf(id, i   1)) != -1) {
        indexes.push(i);
    } // Finds indexes of all object with same id
    if (indexes.length > 1) {
        return true;
    } // if has more than 1 index it returns true (hasDuplicate = true)

    return false; 
}

In your question there is no comma (,) b/w the elements so please edit your question.

  • Related