How to compare elements in array objects using javascript - javascript

I am new to javascript usage.
I have a requirement to compare the field from two different array objects which are having list as below.
Array - A
[
{
"id": "xyz",
"number": "123",
"place": "Here",
"phone": "9090909090"
},
{
"id": "abc",
"number": "456",
"place": "There",
"phone": "9191919191"
},
]
Array - B
[
{
"element1" : "ert",
"id1":"iii",
"element2":"erws",
"element3":"234"
}
,
{
"element1" : "uio",
"id1":"xyz",
"element2":"puy",
"element3":"090"
}
]
The scenario is to compare for each 'id' in the list of array A, with the list of Array B to field 'id1'
Example -
I need to check from Array A -> 'id:xyz' matches the array B object field 'id1'.
Array A - id: xyz should match with id1: xyz in Array B
If the match occurs I need to pull out complete object from the array list A.
here id:xyz matches with id1:xyz
then pull out as below
[
{
"id": "xyz",
"number": "123",
"place": "Here",
"phone": "9090909090"
}
]
Please help me with the suggestions to make this work using javascript.

const A = [
{
"id": "xyz",
"number": "123",
"place": "Here",
"phone": "9090909090"
},
{
"id": "abc",
"number": "456",
"place": "There",
"phone": "9191919191"
},
];
const B = [
{
"element1" : "ert",
"id1":"iii",
"element2":"erws",
"element3":"234"
},
{
"element1" : "uio",
"id1":"xyz",
"element2":"puy",
"element3":"090"
}
];
const C = A.filter(a => B.some(b => b.id1 === a.id));
console.log(C);

// the usage of `const` here means that arrA cannot be re-declared
// this is good for data that should not be changed
const arrA = [{
"id": "xyz",
"number": "123",
"place": "Here",
"phone": "9090909090"
},
{
"id": "abc",
"number": "456",
"place": "There",
"phone": "9191919191"
},
];
const arrB = [{
"element1": "ert",
"id1": "iii",
"element2": "erws",
"element3": "234"
},
{
"element1": "uio",
"id1": "xyz",
"element2": "puy",
"element3": "090"
}
];
// slow method for long lists, fine for short lists or if there are duplicates
// compares each entry in array A to each entry in array B
const out1 = arrA.filter(x => arrB.some(y => x.id === y.id1));
console.log("Example 1: \n", out1);
// faster for long lists
// creates a set of unique values for array B's id1 parameter, ignores duplicates
// then checks that set for each entry in array A
const setB = arrB.reduce((a, b) => {
a.add(b.id1);
return a;
}, new Set());
const out2 = arrA.filter(x => setB.has(x.id));
console.log("Example 2: \n", out2)
.as-console-wrapper { min-height: 100% } /* this is just to make the stack overflow output prettier */

Related

How do I set value of nested object to key of current object?

This array has the key to substitute with nested key of 'name'
const arr = ['status', 'user', ...] <-- This array contains key to be replaced with name
This is what my current response object is
[
{
"id": 11,
"location": "Mumbai",
"status": {
"name": "NEW"
},
"user": {
"name": "Rakesh"
}
}
]
How do I modify the above array of objects to this below
[
{
"id": 11,
"location": "Mumbai",
"status": "NEW",
"user": "Rakesh"
}
]
can try below code
const keys = ['status', 'user']
let arr = [
{
"id": 11,
"location": "Mumbai",
"status": {
"name": "NEW"
},
"user": {
"name": "Rakesh"
}
}
]
arr.map(a => keys.forEach(k => {
if(a[k] && a[k].name) a[k] = a[k].name
}));
console.log(arr);
I'd try this one:
const results = [
{
"id": 11,
"location": "Mumbai",
"status": {
"name": "NEW"
},
"user": {
"name": "Rakesh"
}
}, {
"id": 12,
"location": "Helsinki",
"status": {
"name": "NEW"
},
"user": {
"name": "Samuli"
}
}
];
const flattenObject = ([key, value]) => ((typeof value === 'object') ? {[key] : value[Object.keys(value)[0]]} : {[key]: value});
const reduceToSingleObject = (acc, b) => ({...acc, ...b});
const actualResults = results.map((result) => Object.entries(result).map(flattenObject).reduce(reduceToSingleObject));
console.log(actualResults);
Explanation:
flattenObject is a function to flatten structure of object inside object. This only takes the first prop (without knowing the name of the key). If you, for some reason, would need to flatten several key-values, then it'd need whole different kind of helper function to sort that out.
reduceToSingleObject is a function to put all the key-value pairs into a single object. This could have been done already in flattenObject function, but for the clarity, I separated it to a normal map - reduce pattern.
actualResults is the outcome where we go through all the entries of your original results.

How can I concatenate this type of JSON in javascript?

How can I concatenate this json to obtain it:
complements = ["XYZ 3, CDE TR, AAA 5", "", "NDP 3, DDD FR"] ?
Each address can contain a set of complements which must be concatenated and separated by a comma.
P.s: I'm using javascript.
P.s2: Complements can be null like in the second group in JSON.
[
{
"postalcode": "1234",
"street": "ABC",
"number": "1",
"complement": [
{
"type": "B",
"name": "XYZ",
"description": "3"
},
{
"type": "C",
"name": "CDE",
"description": "TR"
},
{
"type": "D",
"name": "AAA",
"description": "5"
}
]
},
{
"postalcode": "444",
"street": "No complements",
"number": "5"
},
{
"postalcode": "2222",
"street": "BBB",
"number": "2",
"complement": [
{
"type": "E",
"name": "NDP",
"description": "3"
},
{
"type": "F",
"name": "DDD",
"description": "FR"
}
]
}
];
My code I'm getting this.complementsList.forEach is not a function.
getComplement(addressesResponse){
this.complementsList = JSON.parse(addressesResponse);
this.complementsList.forEach((item) => {
Object.defineProperty(item, 'complements', {
get: function() {
return this.complement.map((c) => `${c.name} ${c.description}`).join(', '); }
})
});
Source: https://salesforce.stackexchange.com/questions/367713/how-to-render-a-json-in-the-same-line-lwc
how i solved it :
arr.map((x)=>x.complement != null? (x.complement.map((y)=>y.name+' '+y.description)+"") :'');
Having a javascript object, you can go through the keys of the object and combine some of them into strings
It will look something like this:
const jsonObject = [{...}, {...}, ...]
const complements = [];
jsonObject.forEach((item) => {
let complement = item['complement'].reduce((result, currObj)
=> result += (currObj.name+' '+currObj.description), "");
complements.push(complement);
});
This is just an example. There are many ways to do it.

Find intersection of 2 arrays containing slightly different objects

I'm trying to find the intersection from 2 different arrays that contain slightly different objects.
For example:
const arr1 = [
{
"number":"1234",
"id":"34782",
"firstName":"John",
"lastName":"Smith",
"email":"test1#test.com",
},
{
"number":"1232",
"id":"34783",
"firstName":"Chad",
"lastName":"Baker",
"email":"test2#test.com",
}
];
const arr2 = [
{
"uuid":"0123",
"firstName":"John",
"lastName":"Smith",
"title":"Director"
},
{
"uuid":"0125",
"firstName":"Sam",
"lastName":"Hurst",
"title":"Manager"
}
]
const arr3 = arr1.filter(object => arr2.includes(object));
console.log(arr3);
I'm trying to create a new array that contains only the objects in arr1 where firstName and lastName values are the same in both arrays.
Desired result from above data:
arr3 = [
{
"number":"1234",
"id":"34782",
"firstName":"John",
"lastName":"Smith",
"email":"test1#test.com",
},
]
since this object's firstName and lastName match in both arr1 and arr2
Right now i have this.arr3 = this.arr1.filter(object => this.arr2.includes(object))
But because arr1 and arr2 contain different objects due to proper names, this doesn't work.
Try something like this:
const arr1 = [{
"number": "1234",
"id": "34782",
"firstName": "John",
"lastName": "Smith",
"email": "test1#test.com",
},
{
"number": "1232",
"id": "34783",
"firstName": "Chad",
"lastName": "Baker",
"email": "test2#test.com",
}
];
const arr2 = [{
"uuid": "0123",
"firstName": "John",
"lastName": "Smith",
"title": "Director"
},
{
"uuid": "0125",
"firstName": "Sam",
"lastName": "Hurst",
"title": "Manager"
}
]
const arr3 = arr1.filter(value =>
arr2.some(value2 =>
value.firstName === value2.firstName && value.lastName === value2.lastName
)
);
console.log(arr3);
Basically, use some instead of includes as this allows you to provide a predicate.
I think you can try this :
arr1.filter(item1 => (arr2.find(item2 => (item2.firstName == item1.firstName && item2.lastName == item1.lastName)) != undefined));
It uses the arr2.find function, to check if it contains some item with same firstName and lastName properties.

How to loop through an array of object literals, concatenating values that share a duplicate id? [duplicate]

This question already has answers here:
Merge JavaScript objects in array with same key
(15 answers)
Closed 4 years ago.
I need an efficient way to loop through an array of object literals and concatenate values within the objects that have duplicate IDs.
Is there a more elegant way of doing this versus having multiple for loops nested within each other?
For example, this is the data I am given:
{ "theList": [
{
"id": 101,
"name": "Bubbles' Cat Farm",
"number": "123"
},
{
"id": 102,
"name": "Sunnyvale Park",
"number": "456"
},
{
"id": 101,
"name": "Bubbles' Cat Farm",
"number": "789"
]};
The expected result should be:
{ "theList": [
{
"id": 101,
"name": "Bubbles' Cat Farm",
"number": "123, 789"
},
{
"id": 102,
"name": "Sunnyvale Park",
"number": "456"
]}
You can use reduce
let obj = [{ "id": 101,"name": "Bubbles' Cat Farm","number": "123"},{"id": 102,"name": "Sunnyvale Park","number": "456"},{"id": 101,"name": "Bubbles' Cat Farm","number": "789"}];
let op = obj.reduce((out,inp)=>{
if(out[inp.id]){
out[inp.id].number += ', ' + inp.number;
} else {
out[inp.id] = inp
}
return out
},{})
console.log(Object.values(op))
using reduce and the findIndex function you will be able to achieve what you want.
const array = [{
"id": 101,
"name": "Bubbles' Cat Farm",
"number": "123"
},
{
"id": 102,
"name": "Sunnyvale Park",
"number": "456"
},
{
"id": 101,
"name": "Bubbles' Cat Farm",
"number": "789"
}
]
const result = array.reduce((accum, cv) => {
const index = accum.findIndex(item => item.id === cv.id);
if (index === -1) {
accum.push(cv);
} else {
accum[index].number += ", " + cv.number;
}
return accum;
}, [])
console.log(result)
If number is the only key which has distinct values, then you could do something like this using reduce:
const input = {"theList":[{"id":101,"name":"Bubbles' Cat Farm","number":"123"},{"id":102,"name":"Sunnyvale Park","number":"456"},{"id":101,"name":"Bubbles' Cat Farm","number":"789"}]}
const merged = input.theList.reduce((acc, {id,name,number}) =>{
acc[id]
? acc[id]["number"] += ", " + number
: acc[id] = {id,name,number};
return acc
},{})
const final = { "theList": Object.values(merged) }
console.log(final)
Create an accumulator with each unique id as key and the object you need in the final array as value like this. Then concatenate the number when a id already exists in the accumulator, else add a new key to the accumulator.
{
"101": {
"id": 101,
"name": "Bubbles' Cat Farm",
"number": "123, 789"
}
}
Then use Object.values to get only the values of theList in an array.
You can make your container a dictionary where the key is the ID and eachvalue is an empty list. So when you loop through the original data. If the key doesnt exist, create a list with one item. If the key does exist already, just append the value to the list.

How to merge two javascript arrays based on property values?

I have two arrays
array1 = [{"id":1,"name":"Michale Sharma","gender":"Male","age":25,"salary":10000},{"id":2,"name":"Sunil Das","gender":"Male","age":24,"salary":5000},{"id":3,"name":"Robin Pandey","gender":"Male","age":35,"salary":45000},{"id":4,"name":"Mona Singh","gender":"Female","age":27,"salary":12000}]
array2 = [{"Deptid":1,"Deptname":"IT"},{"Deptid":12,"Deptname":"HR"},{"Deptid":3,"Deptname":"HW"}]
Output:
{ "0": { "id": 1, "name": "Michale Sharma", "gender": "Male", "age": 25, "salary": 10000, "Deptid": 1, "Deptname": "IT" }, "1": { "id": 2, "name": "Sunil Das", "gender": "Male", "age": 24, "salary": 5000}, "2": { "id": 3, "name": "Robin Pandey", "gender": "Male", "age": 35, "salary": 45000, "Deptid": 3, "Deptname": "HW" }, "3": { "id": 4, "name": "Mona Singh", "gender": "Female", "age": 27, "salary": 12000 }, "4" :{ "Deptid": 12, "Deptname": "HR" } }
I want to merge them based on the property values e.g id of array1 and Deptid of array2
Which means if id value = 1 and Deptid value = 1, then merge the records, if not then keep the values from one array and the other will be null. In another words, kind of the functionality of FULL OUTER JOIN. Because the array data cannot be a sequential one and may not be of the same length.
I have tried with Jquery.extend as under
$.extend(true, array1,array2)
It does not accept any property but merges the arrays.
I have also seen this but it does not help.
Looks like you need to have a custom logic. Here is sample using lodash library:
var array1 = [{"id":1,"name":"Michale Sharma","gender":"Male","age":25,"salary":10000},{"id":2,"name":"Sunil Das","gender":"Male","age":24,"salary":5000},{"id":3,"name":"Robin Pandey","gender":"Male","age":35,"salary":45000},{"id":4,"name":"Mona Singh","gender":"Female","age":27,"salary":12000}]
var array2 = [{"Deptid":1,"Deptname":"IT"},{"Deptid":12,"Deptname":"HR"},{"Deptid":3,"Deptname":"HW"}]
var defaults = {
Deptid: null,
DeptName: null
};
_.each(array1, function (obj) {
var dept = _.find(array2, { Deptid: obj.id });
_.defaults(obj, dept, defaults);
});
Using LoDash, roughly something like this:
_.reduce(array1, function(res, item1) {
var found = _.find(array2, function(item2) {
return item1.id === item2.Deptid;
});
if (found) res.push(_.merge({}, item1, found));
return res;
}, []);
EDIT: Sorry, I forgot about merging empty props.
It would be something like this (unoptimized):
function join(array1, array2) {
var keys = _.keys(array2[0]);
var vals = _.map(keys, function() { return '' });
return _.map(array1, function(item1) {
var found = _.find(array2, function(item2) {
return item1.id === item2.Deptid;
});
if (found)
return _.merge({}, item1, found);
return _.merge({}, item1, _.zipObject(keys, vals));
}, []);
}

Categories