Combine 2 arrays based on their common id [duplicate] - javascript

This question already has answers here:
Merge two array of objects based on a key
(23 answers)
Closed 4 months ago.
I have 2 different arrays, that i want to combine.
The first one looks like following:
const Cats[] = [
{ id: '1', name: 'Smiley' },
{ id: '2', name: 'Purple' },
]
the second one:
const catAges[] = [
{ id: '4', age: '13', catId: '1' },
{ id: '5', age: '4', catId: '2' },
];
and i want to combine them where id from Cats[] and catId from catAges[] are the same and have a result like following:
{ id: '4', age: '13', cat: { id: '1', name: 'Smiley' } },
{ id: '5', age: '4', cat: { id: '2', name: 'Purple' } },
i get the arrays from 2 different async functions looking like this:
const cats = [await getByCatId("1"), await getByCatId("2")];
const catsAge = await getCatsAges();
But i need help in how i combine these 2 and map them. I've tried something like this but without any success:
const all = (cats, catsAge) =>
cats.map(cats=> ({
...catsAge.find((cats) => (catsAge.catId === cats.id) && catsAge),
...cats
}));
console.log(all(cats, catsAge));
Thankful for any help in how to move forward.

const Cats = [
{ id: '1', name: 'Smiley' },
{ id: '2', name: 'Purple' },
]
const catAges = [
{ id: '4', age: '13', catId: '1' },
{ id: '5', age: '4', catId: '2' },
];
const transformed = catAges.map(item => {
const cat = Cats.find(cat => cat.id === item.catId);
if (cat) {
item.cat = cat;
delete item.catId;
}
return item;
});
console.log(transformed);

The problem with your function is just that you're re-using the cats variable too much, so in your .find comparision you're comparing an element from catsAge (as cats.id) and the catsAge array (as catsAge.catId) which is undefined.
Try this:
const all = (cats, catsAge) =>
cats.map((cat) => ({
...catsAge.find((catsAge) => catsAge.catId === cat.id),
...cat,
}));
Pro tip: Learn+Use Typescript and the compiler would catch these errors for you :)

const Cats = [
{ id: '1', name: 'Smiley' },
{ id: '2', name: 'Purple' },
]
const catAges = [
{ id: '4', age: '13', catId: '1' },
{ id: '5', age: '4', catId: '2' },
];
catAges.map(catage => {
const cat = Cats.find(c => c.id == catage.catId);
if(cat) {
delete catage.catId;
catage.cat = cat;
return catage;
}
});

Related

How to use some lodash method to check if one property doesnt match within two arrays using javascript?

i have 2 array of objects like so,
const initial = [
{
id: '1',
value: '1',
},
{
id: '2',
value: '2',
}
]
const current = [
{
id: '1',
value: '3',
},
{
id: '2',
value: '2',
},
]
these two arrays are almost the same.
i want to check if the current array has value different than the initial array with same id.
so if atleast one of the object in current has value different from the initial value then it should return true. if not false.
so in above example current array with id 1 has value 3 which is different from initial value with id '1'.
i was trying to do something like below,
const output = current.filter(item => some(initial, {id: item.id, value: !item.value}))
but this doesnt seem to be the right way. could someone help me with this. thanks.
Using Map and Array#map, save the id-value pairs of initial
Using Array#some, iterate over current to compare
const _isDifferent = (initial = [], current = []) => {
const map = new Map( initial.map(({ id, value }) => ([id, value])) );
return current.some(({ id, value }) => map.get(id) !== value);
}
const
initial = [ { id: '1', value: '1' }, { id: '2', value: '2' } ],
current = [ { id: '1', value: '3' }, { id: '2', value: '2' } ];
console.log( _isDifferent(initial, current) );
Based on your code,we can compare the length to find if it has different value
let checkDiffArray = (arr1,arr2) =>
arr1.filter(a1 => arr2.some(a2 => a2.id === a1.id && a2.value === a1.id)).length != arr2.length
const initial = [
{
id: '1',
value: '1',
},
{
id: '2',
value: '2',
}
]
const current = [
{
id: '1',
value: '3',
},
{
id: '2',
value: '2',
},
]
let checkDiffArray = (arr1,arr2) => arr1.filter(a1 => arr2.some(a2 => a2.id === a1.id && a2.value === a1.id)).length != arr2.length
console.log(checkDiffArray(initial,current))
You can use the differenceWith combined with the isEqual
const initial = [
{ id: '1', value: '1' },
{ id: '2', value: '2' }
]
const current = [
{ id: '1',value: '3' },
{ id: '2',value: '2' },
]
const output = Boolean(_.differenceWith(current, initial, _.isEqual).length);
console.log(output);
<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>

How to remove data with same id in an array of object using javascript?

in an arry of objects i want to remove object which have same id (duplicated data) using javascript.
below is the input array
const input = [
{
id: '1',
name: 'first',
},
{
id: '1',
name: 'first',
},
{
id: '2',
name: 'second',
},
{
id: '2',
name: 'second',
},
]
so as you see from above array there are duplicating data with id '1' and '2'.
if there is similar id i want include only one
so the expected output is like below,
const output = [
{
id: '1',
name: 'first',
},
{
id: '2',
name: 'second',
},
]
how can i do this. could someone help me with this. i am new to programming thanks.
You can use reduce to filter data from the array based on some condition like bellow
const input = [
{
id: '1',
name: 'first',
},
{
id: '1',
name: 'first',
},
{
id: '2',
name: 'second',
},
{
id: '2',
name: 'second',
},
]
const result = input.reduce((accumulator, current) => {
let exists = accumulator.find(item => {
return item.id === current.id;
});
if(!exists) {
accumulator = accumulator.concat(current);
}
return accumulator;
}, []);
console.log(result);
Similar to this answer. You will have to change the const to let while declaring input though, or use a new variable I suppose.
filtered_input = input.filter((value, index, self) =>
index === self.findIndex((t) => (
t.id === value.id
))
)
There is a lot of good approachs here.
Here is my approach for removing matching property from the original array and sending it back in the return if found.
I prefer to use this one, if you are looping through a external array and matching them, this way you dont need to loop through the whole array again and again for each, because while you are finding the matches it keeps removing them from the original array, increasing performance.
Note that this will return the first match found
let id = "601985b485d9281d64056953"
let contacts = [{
...,
parent: "601985b485d9281d64056953",
...,
},
{
...,
parent: "601985b485d9281d64065128",
...,
}
]
function findAndRemoveObjectFromArray(array, internalProperty, externalProperty, convertType = "string", returnObject = false) {
let objIndex = -1
if (convertType === "string") objIndex = array.findIndex((obj) => String(obj[`${internalProperty}`]) === String(externalProperty));
if (convertType === "number") objIndex = array.findIndex((obj) => Number(obj[`${internalProperty}`]) === Number(externalProperty));
if (objIndex > -1) {
const object = array.splice(objIndex, 1);
if (returnObject) return object.shift()
return object
}
return [];
}
let currentContact = findAndRemoveObjectFromArray(contacts, "parent", id, 'string', true)
// Results:{..., parent: "601985b485d9281d64056953",...}
you could use Set to get rid of the duplicate data like this
const input = [
{
id: '1',
name: 'first',
},
{
id: '1',
name: 'first',
},
{
id: '2',
name: 'second',
},
{
id: '2',
name: 'second',
},
]
const result = [...new Set(input.map(JSON.stringify))].map(JSON.parse)
console.log(result)
Below is another approach
const input = [
{
id: '1',
name: 'first',
},
{
id: '1',
name: 'first',
},
{
id: '2',
name: 'second',
},
{
id: '2',
name: 'second',
},
];
const uniqueIds = new Set();
const uniqueList = input.filter(element => {
const isDuplicate = uniqueIds.has(element.id);
uniqueIds.add(element.id);
return !isDuplicate;
});
console.log(uniqueList);

Create an array of object from given array key

I have array like this .
const test = [
{ student: { id : '1', Name: 'A' }, marks: {
 id: '2', Name: 'B'
} },
{ student: {
 id : '3', Name: 'C' }, marks: { id: '4', Name: 'D' } }
]
Now, from this array of object , I am trying to create two diff arrays which will be having seperate student and marks keys .
const student = [{"student":{"Id": {value: "A"}}}, {"student":{"Id": {value: "B"}}}]
and for marks
const marks = [{"marks":{"Id": {value: "C"}}}, {"marks":{"Id": {value: "D"}}}]
SO, Here what I tried is
test.map((index,item) => {
return [item.student]
})
can any one help me with this ?
Thanks.
You want a new object returned, not a sub array.
Following uses destructuring to simplify the returned object
const test = [
{ student: { id : '1', Name: 'A' }, marks: {
id: '2', Name: 'B'
} },
{ student: {
id : '3', Name: 'C' }, marks: { id: '4', Name: 'D' } }
]
const students = test.map(({student}) => ({student}))
const marks = test.map(({marks}) => ({marks}))
console.log(students)
console.log(marks)

Javascript filter method, Remove all Items with matching values in array

I'm trying to remove all items if they match with array values but it's removing only one item. How can i remove all items with filter method or what is the best way to achieve this.
let data = [
{
id: '1',
title: 'ABC'
},
{
id: '2',
title: 'DEF'
},
{
id: '3',
title: 'GHI'
},
{
id: '4',
title: 'JKL'
},
{
id: '5',
title: 'MNO'
}
]
data = data.filter(post => {
let remove = ['2', '4', '5']
for(let i = 0; i < remove.length; i++) {
return post.id !== remove[i]
}
})
console.log(data)
Thanks
you should return false if you want to remove item from array
let data = [
{
id: '1',
title: 'ABC'
},
{
id: '2',
title: 'DEF'
},
{
id: '3',
title: 'GHI'
},
{
id: '4',
title: 'JKL'
},
{
id: '5',
title: 'MNO'
}
]
let remove = ['2', '4', '5']
data = data.filter(post => {
return !remove.includes(post.id);
})
console.log(data)
All the notice are in the snippet's comment
let data = [ { id: '1', title: 'ABC' }, { id: '2', title: 'DEF' }, { id: '3', title: 'GHI' }, { id: '4', title: 'JKL' }, { id: '5', title: 'MNO' } ]
const remove = ['2', '4', '5']
// `indexOf` is from ES5
data = data.filter(post => remove.indexOf(post.id) === -1)
console.log(data)
// `includes` is from ES7
data = data.filter(post => !remove.includes(post.id))
console.log(data)
// this will recreate the array ['2', '4', '5'] 5 times
data = data.filter(post => !['2', '4', '5'].includes(post.id))
console.log(data)
There is no need to use for loop inside of filter.
Instead it is possible to use some method inside of filter. The some method checks whether at least one element satisfies condition inside of provided function. So unnecessary iteration will be avoided:
data.filter(f => !remove.some(s => s == f.id))
An example:
let data = [
{
id: '1',
title: 'ABC'
},
{
id: '2',
title: 'DEF'
},
{
id: '3',
title: 'GHI'
},
{
id: '4',
title: 'JKL'
},
{
id: '5',
title: 'MNO'
}
]
let remove = ['2', '4', '5']
console.log(data.filter(f => !remove.some(s => s == f.id)));
I'll suggest using includes rather then a nested for loop.
You should also move the remove var outside of the loop, so it's not reinitialised every time.
The callback to the filter method is a predicate. If the condition evaluates to true, the current value in the iteration will be returned. In your case, you want to return if the current value is not in the remove array.
let data = [
{
id: '1',
title: 'ABC'
},
{
id: '2',
title: 'DEF'
},
{
id: '3',
title: 'GHI'
},
{
id: '4',
title: 'JKL'
},
{
id: '5',
title: 'MNO'
}
]
const remove = ['2', '4', '5']
data = data.filter(post => {
return !remove.includes(post.id)
})
console.log(data)

How to use array.filter + map on an array

I'm trying to filter this array to get the id and convert from a string to a number. I want to use filter and map? Wanting to know how to make it as clear as possible.
var pets = [
{ id: '1', name: 'rupert', readyForHome: 'No', age: 12, personality: ['friendly', 'lazy', 'loving']},
{ id: '2', name: 'mrs fluffy', readyForHome: 'Yes', age: 2, personality: ['affectionate', 'playful', 'shy']},
{ id: '3', name: 'tabitha', readyForHome: 'Yes', age: 4, personality: ['aggressive', 'independent']},
{ id: '4', name: 'lily', readyForHome: 'No', age: 8, personality: ['friendly', 'playful', 'mischievous']},
];
All you need is map to get down to an array of ids as numbers:
pets = pets.map(function(pet) {
return Number(pet.id);
});
var pets=[{id:"1",name:"rupert",readyForHome:"No",age:12,personality:["friendly","lazy","loving"]},{id:"2",name:"mrs fluffy",readyForHome:"Yes",age:2,personality:["affectionate","playful","shy"]},{id:"3",name:"tabitha",readyForHome:"Yes",age:4,personality:["aggressive","independent"]},{id:"4",name:"lily",readyForHome:"No",age:8,personality:["friendly","playful","mischievous"]}];
pets = pets.map(function(pet) {
return Number(pet.id);
});
console.log(pets);
var petIds = pets.map(function (pet) {
petId = parseInt(pet.id);
return petId;
});

Categories