Remove duplicate objects from object array - arrays

I have a list of arrays i need to hide the duplicates of array
{
"company_name": "SERVICE INDUSTRIES LTD.",
"claim_id": "2017\/04\/LHRHHDP00015-2018-00702",
},
{
"company_name": "KARACHI CHAMBER OF COMMERCE & INDUSTRY",
"claim_id": "2018\/03\/HOHHDP00013-2019-00098",
},
{
"company_name": "PAKISTAN RED CRESCENT SOCIETY",
"claim_id": "2017\/04\/LHRHHDP00015-2018-00702",
},
{
"company_name": "SERVICE INDUSTRIES LTD.",
"claim_id": "2018\/04\/LHRHHDP00022-2019-01292",
},
{
"company_name": "U MICROFINANCE BANK LTD",
"claim_id": "2017\/04\/LHRHHDP00015-2018-00702",
}
This is the example array i need to hide the array which have duplicate claim_id.

You can use a filter and findIndex to find duplicates. If the index does not equal the current item, there is a duplicate.
The performance impact is maximum 1.5x the size of the array:
const unique = data.filter((item, index) =>
data.findIndex(({ claim_id }) => item.claim_id === claim_id) === index
);

To solve this easily let's use this strategy:
Extract values from the array to an object (used as a dictionary)
Eliminating duplication
Extract values to a new array
so....
const dic = {}
for (const item of originalArray) {
dic[item.claim_id] = item
}
const groupedArray = Object.values(dic)
The only question is... where's typescript? we used native JS and managed just fine :)

Related

React - Update or Replace an Object with in the State object

I have an State varaible with array of objects like this.
type State = {
Dp: ArrayDataProvider<string, Message>;
};
Inside Dp i will have data which will hold the data in the form of array like this.
[{
"id": 1,
"name": "January",
"abc": abc,
"xyz": xyz
}, {
"id": 2,
"name": "February",
"abc": abc,
"xyz": xyz
}]
I want to replace the object which is having id 2 with the different object and i want to have my object like this .
[{
"id": 1,
"name": "January",
"abc": abc,
"xyz": xyz
}, {
"id": 2,
"name": "New month",
"abc": 1234abc,
"xyz": someVlaue
}]
how to do it in efficient way with typescript in react.
I have done something like this but not working
const data = this.state.Dp?.data.slice();
const index = data.findIndex(currentItem => {
return currentItem.id === updateData[0].id;
});
data[index] = updateData;
this.state.Dp.data = data;
this.setState({ Dp: this.state.Dp });
I use map to do this:
const data = this.state.Dp?.data.map(currentItem => {
return currentItem.id === updatedItem.id ? updatedItem : currentItem;
})
map creates a new array with the items from the previous array, but it gives you an opportunity to make adjustments to the items in the new array as it iterates through them. In my example, I'm checking the id of the item to see if it's the one you want to update, and swapping in your updatedItem if the ids match.
I'm not sure about the TypeScript part, to be honest. I haven't worked with it yet.
Note - I'm not sure what form your updateData is in, so you might have to adjust that. It seems like you want it to be an object, but in one of your lines you're treating it like an array.
Use findIndex to find index of the object where id is equal 2, then replace new object to that place.
let tempArray = [...array];
const index = tempArray.findIndex((element) => element.id === 2);
tempArray[index] = {
id: 2,
name: "New month",
abc: "1234abc",
xyz: "someVlaue"
};
setArray(tempArray);

Lodash Merge not updating object with correct values

I am trying to merge these two objects using Lodash merge.
Server object:
[
{
"id": "74738",
"customerId": "534430"
},
{
"id": "74742",
"customerId": "534429"
}
]
Local Object
[
{
"customerId": "534429"
"name": "ABC"
},
{
"customerId": "534430",
"name": "XYZ"
},
]
I am using lodash merge to combine these two objects based on attributes, I am using this code below:
merge({}, serverObject, localObject);
// Output: [{"id":"74738","customerId":"534429","name":"ABC"},{"id":"74742","customerId":"534430","name":"XYZ"}]
The object is not being updated based on the Customer Ids but instead by the sequence of local object.
Expected Output:
[{"id":"74738","customerId":"534430","name":"ABC"},{"id":"74742","customerId":"534429","name":"XYZ"}]
With lodash you can combine all arrays to a single one using _.flatten(), group by a predicate, and then map and merge each group to a single object.
Note: since your customerId is an integer, the items would be ordered by the numerical value.
const { map, groupBy, flatten, merge } = _
const fn = (predicate, ...arrs) => map(
groupBy(flatten(arrs), predicate),
group => merge({}, ...group)
)
const arr1 = [{"id":"74738","customerId":"534430"},{"id":"74742","customerId":"534429"}]
const arr2 = [{"customerId":"534429","name":"ABC"},{"customerId":"534430","name":"XYZ"}]
const result = fn('customerId', arr1, arr2)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
If you need to preserve the original order, flatten to a single array, and then reduce the items to a Map using the result of the predicate as the key. Merge each new item with the same key to the existing one in the Map. Convert the Map's values back to an array using Array.from():
const fn = (predicate, ...arrs) => Array.from(arrs
.flat()
.reduce((acc, o) => {
const key = predicate(o)
return acc.set(key, { ...acc.get(key), ...o })
}, new Map()).values()
)
const arr1 = [{"id":"74738","customerId":"534430"},{"id":"74742","customerId":"534429"}]
const arr2 = [{"customerId":"534429","name":"ABC"},{"customerId":"534430","name":"XYZ"}]
const result = fn(o => o.customerId, arr1, arr2)
console.log(result)

trying to push two specific values into another array as a key value pair using typescript

Newbie here and this is a project I'm building to learn. I'm going around in circles so forgive my ignorance please. I'm now not even sure that what I want to do is possible. I also understand that there are probably better ways to achieve my ultimate goal but this is what I have.
I have an array that includes some user input.
"participants": [ {
"name": "Cristina",
"email": "cristina#gmail",
"yourPerson": "Richard",
"spouseEmail": "Richard#gmail" } ] }
I want to pull the "name" and "youPerson" values and use them as a key:value pair. So name would be the key and yourPerson would be the value.
I thought I could use a forEach but no matter what I do I either get an undefined array or I copy the entire array, not just those two fields.
here is my code at the moment:
participantArray = [];
namePlusSpouseArray = [];
submitParticipant() {
this.participantArray.push(this.participantForm.value);
console.log(this.participantArray)
this.createNamePlusSpouseArray();
}
createNamePlusSpouseArray() {
this.participantArray.forEach(name => {
this.namePlusSpouseArray.push(this.participantArray[name]);
console.log(this.namePlusSpouseArray)
});
}
Not sure if you want a result array of key value pairs, or you want 1 object/map/dictionary/lookup of name -> youPerson
Assuming you want an array containing key value pairs, you can use map
this.namePlusSpouseArray = this.participantArray.map(participant => ({
[participant.name]: participant.youPerson
});
If you want a lookup of name -> youPerson, the "namePlusSpouseArray" shouldn´t be an array but instead just an object
namePlusSpouseLookup = {};
this.participantArray.forEach(participant => {
this.namePlusSpouseLookup[participant.name] = participant.youPerson;
});
The simplest solution is:
const participantArray = {
"participants": [ { "name": "Cristina", "email": "cristina#gmail", "yourPerson": "Richard", "spouseEmail": "Richard#gmail" } ] };
const createPair = participants => {
return participants.map(participant =>
({ [participant.name]: participant.yourPerson}))
}
console.log(createPair(participantArray.participants));

Remove duplicate content from array

"name": [
{
"name": "test1"
},
{
"name": "test2"
},
{
"name": "test3"
},
{
"name": "test1"
},
]
I have the above created by nodejs. During array push, I would like to remove duplicated arrays from the list or only push the name array if the individual array does not exist.
I have tried below codes but it changes the array.
var new = [];
for (var i =0;i<name.length;i++){
new['name'] = name[i].name;
}
The easiest way is probably with Array.prototype.reduce. Something along these lines, given your data structure:
obj.name = Object.values(obj.name.reduce((accumulator, current) => {
if (!accumulator[current.name]) {
accumulator[current.name] = current
}
return accumulator
}, {}));
The reduce creates an object that has keys off the item name, which makes sure that you only have unique names. Then I use Object.values() to turn it back into a regular array of objects like in your data sample.
the solution can be using temp Set;
const tmpSet = new Set();
someObj.name.filter((o)=>{
const has = tmpSet.has(o.name);
tmp.add(o.name);
return has;
});
the filter function iterating over someObj.name field and filter it in place if you return "true". So you check if it exists in a tmp Set & add current value to Set to keep track of duplicates.
PS: new is a reserved word in js;
This should do it
const names = ['John', 'Paul', 'George', 'Ringo', 'John'];
let unique = [...new Set(names)];
console.log(unique); // 'John', 'Paul', 'George', 'Ringo'
https://wsvincent.com/javascript-remove-duplicates-array/

Typescript filter array of object by another array of strings

i stuck at my typescript filter function.
I have an array of objects:
[
{
"id": 12345,
"title": "Some title",
"complexity": [
{
"slug": "1" // my search term
"name": "easy"
}, {
"slug": "2" // my search term
"name": "middle"
},
{...}
And i have a array of strings with the allowed complexity:
public allowedComplexityArray:Array<string> = ["1"];
My Task: I only want to show objects with the allowed complexity of "1".
But somehow my function dont work and i dont know why:
allowedMeals = meals.filter(meal => {
return meal.complexity.every(complexityObj => that.allowedComplexityArray.indexOf(complexityObj.slug) > -1)
});
try:
let allowedMeals = data.filter(meal => {
return meal.complexity.findIndex(complexityObj =>
allowedComplexityArray.findIndex(m => m == complexityObj.slug) > -1) > -1
});
I'm using findIndex instead of filter in the return clause so it does not need to scan the whole array every time.

Resources