Compare 2 Arrays of Objects - javascript

I want to compare 2 Arrays of Objects to find the object or objects which is not matched.
In the example below it should output {label: 'Addition', type: 'address', name: 'address_4', defaultValue: 'test'} as this Object is not matched.
const A = [{
label: 'Street Name',
type: 'address',
name: 'address_1',
defaultValue: 'test1'
},
{
label: 'House Number',
type: 'address',
name: 'address_2',
defaultValue: '1563l1'
},
{
label: 'Addition',
type: 'address',
name: 'address_3',
defaultValue: 'ABC684'
}
]
const B = [{
label: 'Street Name',
type: 'address',
name: 'address_1',
defaultValue: 'test1'
},
{
label: 'House Number',
type: 'address',
name: 'address_2',
defaultValue: '1563l1'
},
{
label: 'Addition',
type: 'address',
name: 'address_3',
defaultValue: 'ABC684'
},
{
label: 'Addition',
type: 'address',
name: 'address_4',
defaultValue: 'test'
}
]
const newSet = A;
const currentSet = B;
let difference = currentSet.filter((page1) => !newSet.find(page2 => page1.name === page2.name))
console.log(difference);
This does not work. It outputs an empty Array. What I'm doing wrong?

You might by comparing A with B which returns an empty array because there is no element in A which doesn't exist in B instead you should compare B with A.
Below code will return an empty array
const A = [
{
label: "Street Name",
type: "address",
name: "address_1",
defaultValue: "test1",
},
{
label: "House Number",
type: "address",
name: "address_2",
defaultValue: "1563l1",
},
{
label: "Addition",
type: "address",
name: "address_3",
defaultValue: "ABC684",
},
];
const B = [
{
label: "Street Name",
type: "address",
name: "address_1",
defaultValue: "test1",
},
{
label: "House Number",
type: "address",
name: "address_2",
defaultValue: "1563l1",
},
{
label: "Addition",
type: "address",
name: "address_3",
defaultValue: "ABC684",
},
{
label: "Addition",
type: "address",
name: "address_4",
defaultValue: "test",
},
];
let difference = A.filter((page1) => {
const result = B.find((page2) => page1.name === page2.name);
return !result;
});
console.log(difference);
You should compare B with A as:
const A = [
{
label: "Street Name",
type: "address",
name: "address_1",
defaultValue: "test1",
},
{
label: "House Number",
type: "address",
name: "address_2",
defaultValue: "1563l1",
},
{
label: "Addition",
type: "address",
name: "address_3",
defaultValue: "ABC684",
},
];
const B = [
{
label: "Street Name",
type: "address",
name: "address_1",
defaultValue: "test1",
},
{
label: "House Number",
type: "address",
name: "address_2",
defaultValue: "1563l1",
},
{
label: "Addition",
type: "address",
name: "address_3",
defaultValue: "ABC684",
},
{
label: "Addition",
type: "address",
name: "address_4",
defaultValue: "test",
},
];
let difference = B.filter((page1) => {
const result = A.find((page2) => page1.name === page2.name);
return !result;
});
console.log(difference);
If there is a case where you want to get the difference between two array then you can do as:
const [small, large] = A.length < B.length ? [A, B] : [B, A];
let difference = large.filter((page1) => {
const result = small.find((page2) => page1.name === page2.name);
return !result;
});

Related

Convert nested JSON Object into a specific array format

I have nested JSON object looking like below and this JSON object I have to convert into some particular format which I have given below:
let jsonObj ={"data": {
"cardShop": {
"cardData": {
"cardTitle": "The Platinum Card<sup>®</sup>",
"cardType": "credit-cards",
"dtmProductName": "PlatinumCard",
"viewAllCards": {
"url": "credit-cards/all-cards",
"text": "All Cards"
}
},
"eligibilityChecker": {
"header": "Check your eligibility",
"subHeader": "The Platinum Card®",
"bulletPoints": [
"Only takes a couple of minutes to complete",
"Will not impact your credit rating",
"Allows you to apply with confidence"
]
}
}
}
}
And the above JSON object I have to convert it to the below format with some new properties like key, title, parentId, id, etc..
[
{
id: "cardShop",
key: "cardShop",
title: "cardShop",
selectable: false,
children: [
{
id: "cardData",
path:"cardShopCardData"
key: "cardData",
title: "cardData",
parentId: "cardShop",
selectable: false,
children: [
{
id: "cardTitle",
path :"cardShopcardDatacardTitle"
key: "cardTitle",
title: "cardTitle",
parentId: "cardData",
isLeaf: true,
children: []
},
{
id: "cardType",
key: "cardType",
title: "cardType",
parentId: "cardData",
isLeaf: true,
children: []
},
{
id: "dtmProductName",
key: "dtmProductName",
title: "dtmProductName",
parentId: "cardData",
isLeaf: true,
children: []
},
{
id: "viewAllCards",
key: "viewAllCards",
title: "viewAllCards",
parentId: "cardData",
selectable: false,
children: [
{
id: "url",
key: "url",
title: "url",
parentId: "viewAllCards",
isLeaf: true,
},
{
id: "text",
key: "text",
title: "text",
parentId: "viewAllCards",
isLeaf: true,
}
]
}
]
},
{
id: "eligibilityChecker",
key: "eligibilityChecker",
title: "eligibilityChecker",
parentId: "cardData",
selectable: false,
children: [
{
id: "header",
key: "header",
title: "header",
parentId: "eligibilityChecker",
},
{
id: "subHeader",
key: "subHeader",
title: "subHeader",
parentId: "eligibilityChecker",
},
{
id: "bulletPoints",
key: "bulletPoints",
title: "bulletPoints",
parentId: "eligibilityChecker",
},
{
id: "image",
key: "image",
title: "image",
parentId: "eligibilityChecker",
}
]
}
]
}
];
I have tried below things. For each object I need a parentId.
let prevKey =""
const iterate = (obj) => {
Object.keys(obj).forEach(key => {
if (typeof obj[key] === 'object' && obj[key] !== null) {
let c ={
id:key,
title:key,
selelected:false,
children:[]
};
if(prevKey && Object.keys(output).length === 0){
output ={
children :[]
}
output.children.push(c)
}
else if(prevKey ){
output.children.push(c)
} else{
output = c
}
prevKey = key;
iterate(obj[key])
}
else{
let c ={
id:key,
title:key,
selelected:false,
children:[]
};
output.children[0].children.push(c)
}
})
}
I have tried using recursion but somehow I am not able to get an expected output.
you can do something like this
const transform = data => {
const loop = (data, parent) => Object.entries(data).map(([key, value]) => {
let additional = parent? {
parentId: parent
}:{}
if(typeof value === 'object' && !Array.isArray(value)){
additional = {
...additional,
selectable: false,
children: loop(value, key)
}
}else{
additional.isLeaf = true
}
return {
id: key,
key,
title: key,
...additional
}
})
return loop(data)
}
let jsonObj = {
"data": {
"cardShop": {
"cardData": {
"cardTitle": "The Platinum Card<sup>®</sup>",
"cardType": "credit-cards",
"dtmProductName": "PlatinumCard",
"viewAllCards": {
"url": "credit-cards/all-cards",
"text": "All Cards"
}
},
"eligibilityChecker": {
"header": "Check your eligibility",
"subHeader": "The Platinum Card®",
"bulletPoints": [
"Only takes a couple of minutes to complete",
"Will not impact your credit rating",
"Allows you to apply with confidence"
]
}
}
}
}
console.log(transform(jsonObj.data))

Comparing two arrays - removing element from array based on object keys

I have two objects.
const arrayOne = [
{
label: "Categories",
to: "/categories",
id: "product_type",
},
{
label: "Colors",
to: "/colors",
id: "color",
},
{
label: "Materials",
to: "/materials",
id: "material",
},
{
label: "Sizes",
to: "/sizes",
id: "sizes",
},
{
label: "Designers",
to: "/designers",
id: "designer_slug",
},
{
label: "Stores",
to: "/stores",
id: "retailer_slug",
},
];
const arrayTwo = [
{
id: "gender",
label: "Gender",
lazy_loaded: false,
},
{
id: "product_type",
label: "Category",
lazy_loaded: false,
},
{
id: "quick_filters",
label: "Quick filters",
lazy_loaded: false,
},
{
id: "final_price",
label: "Price",
lazy_loaded: false,
},
{
id: "color",
label: "Color",
lazy_loaded: false,
},
{
id: "material",
label: "Material",
lazy_loaded: false,
},
{
id: "designer_slug",
label: "Brand",
lazy_loaded: true,
},
{
id: "retailer_slug",
label: "Store",
lazy_loaded: true,
},
];
As you can see they both have the key 'id'. If the IDs in arrayOne aren't in arrayTwo, I would like them to be removed from arrayOne (the whole object). So in this case, only the object with "sizes" should be removed from arrayOne. How would I go about doing this? Thanks in advance!
you could utilize filter:
const newArrayOne = arrayOne.filter(x => arrayTwo.find(y => y.id === x.id))
You could use a Set with id and filter the other array.
const
arrayOne = [{ label: "Categories", to: "/categories", id: "product_type" }, { label: "Colors", to: "/colors", id: "color" }, { label: "Materials", to: "/materials", id: "material" }, { label: "Sizes", to: "/sizes", id: "sizes" }, { label: "Designers", to: "/designers", id: "designer_slug" }, { label: "Stores", to: "/stores", id: "retailer_slug" }],
arrayTwo = [{ id: "gender", label: "Gender", lazy_loaded: false }, { id: "product_type", label: "Category", lazy_loaded: false }, { id: "quick_filters", label: "Quick filters", lazy_loaded: false }, { id: "final_price", label: "Price", lazy_loaded: false }, { id: "color", label: "Color", lazy_loaded: false }, { id: "material", label: "Material", lazy_loaded: false }, { id: "designer_slug", label: "Brand", lazy_loaded: true }, { id: "retailer_slug", label: "Store", lazy_loaded: true }],
two = new Set(arrayTwo.map(({ id }) => id)),
result = arrayOne.filter(({ id }) => two.has(id));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

How to filter nested arrays by searching

I have an array of objects that I want to filter by comparing a nested property to a search term.
For example:
let array = [
{
category: 15,
label: "Components",
value: "a614741f-7d4b-4b33-91b7-89a0ef96a099",
children: [
{
category: 1,
label: "Carousel1",
diId: 55946,
// as you can see there are many children nested array of object
children: [{ label: "nodatafoundmessage", value: "47d18fb2-3e63-4542-ad0e-e5e09acb5016", children: [] }],
value: "be5e027b-9163-4cfb-8816-0c8e3b816086"
},
{
category: 2,
label: "Checkbox1",
diId: 193909,
children: [{ label: "datafound", value: "47d18sb2-3e63-4542-ad0e-e5e09acb5016", children: [] }],
value: "045e8786-2165-4e1e-a839-99b1b0ceef57"
}
]
},
{
value: "4be22726-850c-4905-ab3b-039fcf607d55",
label: "Default",
children: [
{
category: 5,
defaultValueType: 1,
label: "Empty",
toType: "String",
value: "ebedb43f-4c53-491f-8954-d030321845cd"
},
{
category: 5,
defaultValueType: 2,
label: "Space",
toType: "String",
value: "2d0e1429-572b-4f21-9f83-3340bafff95a"
},
{
category: 5,
defaultValueType: 8,
label: "Current Username",
toType: "String",
value: "25f6b40a-33c7-4f17-b29d-99e8d1e4e33c"
},
{
category: 5,
defaultValueType: 9,
label: "Current Location",
toType: "Location",
value: "ed59da2f-318d-4599-9085-4d9d769a27d7"
}
]
},
{
category: 4,
label: "Fixed Value",
isFixed: true,
value: "28e90e3e-a20b-4499-9593-061a7d1e7bd6"
// as you can see there is no children in this object
}
]};
What I'm trying to achieve is if I search for 'nodata' for example my result should be
let array = [
{
category: 15,
label: "Components",
value: "a614741f-7d4b-4b33-91b7-89a0ef96a099",
children: [
{
category: 1,
label: "Carousel1",
diId: 55946,
// as you can see there are many children nested array of object
children: [{ label: "nodatafoundmessage", value: "47d18fb2-3e63-4542-ad0e-e5e09acb5016", children: [] }],
value: "be5e027b-9163-4cfb-8816-0c8e3b816086"
}
]
}
];
Another option if I search for 'spa' my result should be
let array = [
{
value: "4be22726-850c-4905-ab3b-039fcf607d55",
label: "Default",
children: [
{
category: 5,
defaultValueType: 2,
label: "Space",
toType: "String",
value: "2d0e1429-572b-4f21-9f83-3340bafff95a"
}
]
}
];
I have been super confused and I decided to get some help. Thank you for your helps guys!
The following function should do the trick for you:
function searchData(dataArray, searchTerm) {
return dataArray.flatMap(obj => {
const objHasSearchTerm = Object.entries(obj)
.some(([key, value]) => key !== 'children' && String(value).toLowerCase().includes(searchTerm.toLowerCase()));
if (objHasSearchTerm && !obj.children) return [obj];
const matchedChildren = searchData(obj.children ?? [], searchTerm);
return objHasSearchTerm || matchedChildren.length > 0
? [{
...obj,
children: matchedChildren,
}]
: [];
})
}
It recursively goes through the data array, looks for any entries that have the specified search term, and if so, places it into the newly constructed object. It will preserve the nested shape of the object, which may or may not be what is needed. Feel free to tweak the algorithm to your own needs.
let allData = [
{
category: 15,
label: "Components",
value: "a614741f-7d4b-4b33-91b7-89a0ef96a099",
children: [
{
category: 1,
label: "Carousel1",
diId: 55946,
// as you can see there are many children nested array of object
children: [{ label: "nodatafoundmessage", value: "47d18fb2-3e63-4542-ad0e-e5e09acb5016", children: [] }],
value: "be5e027b-9163-4cfb-8816-0c8e3b816086"
},
{
category: 2,
label: "Checkbox1",
diId: 193909,
children: [{ label: "datafound", value: "47d18sb2-3e63-4542-ad0e-e5e09acb5016", children: [] }],
value: "045e8786-2165-4e1e-a839-99b1b0ceef57"
}
]
},
{
value: "4be22726-850c-4905-ab3b-039fcf607d55",
label: "Default",
children: [
{
category: 5,
defaultValueType: 1,
label: "Empty",
toType: "String",
value: "ebedb43f-4c53-491f-8954-d030321845cd"
},
{
category: 5,
defaultValueType: 2,
label: "Space",
toType: "String",
value: "2d0e1429-572b-4f21-9f83-3340bafff95a"
},
{
category: 5,
defaultValueType: 8,
label: "Current Username",
toType: "String",
value: "25f6b40a-33c7-4f17-b29d-99e8d1e4e33c"
},
{
category: 5,
defaultValueType: 9,
label: "Current Location",
toType: "Location",
value: "ed59da2f-318d-4599-9085-4d9d769a27d7"
}
]
},
{
category: 4,
label: "Fixed Value",
isFixed: true,
value: "28e90e3e-a20b-4499-9593-061a7d1e7bd6"
// as you can see there is no children in this object
}
];
function searchData(dataArray, searchTerm) {
return dataArray.flatMap(obj => {
const objHasSearchTerm = Object.entries(obj)
.some(([key, value]) => key !== 'children' && String(value).toLowerCase().includes(searchTerm.toLowerCase()));
if (objHasSearchTerm && !obj.children) return [obj];
const matchedChildren = searchData(obj.children ?? [], searchTerm);
return objHasSearchTerm || matchedChildren.length > 0
? [{
...obj,
children: matchedChildren,
}]
: [];
})
}
console.log('----- Search: nodata')
console.log(JSON.stringify(searchData(allData, 'nodata'), null, 2))
console.log('----- Search: spa')
console.log(JSON.stringify(searchData(allData, 'spa'), null, 2))

Dynamically deleting the column from multidimensional array of object value

I am trying to delete the column from multidimensional array of objects,
below is the multidimensional array of objects and the code I have tried: -
const array1 = [
[{
checked: false,
id: 13993,
type: "checkbox",
},
{
checked: false,
id: 13995,
type: "label",
},
{
checked: false,
id: 13998,
type: "label",
},
{
checked: false,
id: 13940,
type: "label",
},
],
[{
checked: false,
id: 13993,
type: "checkbox",
},
{
checked: false,
id: 13995,
type: "label",
},
{
checked: false,
id: 13998,
type: "checkbox",
},
{
checked: false,
id: 13940,
type: "label",
},
],
[{
checked: false,
id: 13993,
type: "checkbox",
},
{
checked: false,
id: 13995,
type: "label",
},
{
checked: false,
id: 13998,
type: "checkbox",
},
{
checked: false,
id: 13940,
type: "label",
},
],
[{
checked: false,
id: 13993,
type: "label",
},
{
checked: false,
id: 13995,
type: "label",
},
{
checked: false,
id: 13998,
type: "label",
},
{
checked: false,
id: 13940,
type: "label",
},
]
];
array1.map((a, i) => {
a.splice(2, 1);
console.log(a)
return a;
});
console.log(array1);
In the above array i want to remove column second and fourth column as they are same value,
The above logic i found, but here instead of 2 i want to pass index dynamically , i have tried lot combinations it dint work, also i tried to pass array1 index but not deleting correct column.
If i pass index as dynamically then in the array if the column is repeated it will delete automatically.
Below is the expected output:-
result = [
[{
checked: false,
id: 13993,
type: "checkbox",
},
{
checked: false,
id: 13998,
type: "label",
},
],
[{
checked: false,
id: 13993,
type: "checkbox",
},
{
checked: false,
id: 13998,
type: "label",
},
],
[{
checked: false,
id: 13993,
type: "checkbox",
},
{
checked: false,
id: 13998,
type: "label",
},
],
[{
checked: false,
id: 13993,
type: "checkbox",
},
{
checked: false,
id: 13998,
type: "label",
},
],
];
here is below image of array, marked one needs to be deleted:
Maybe you can try like below
let arr = [
[1, 2, 3, 4, 24, 'c'],
['a', 2, 3, 'b', 24, 'd']
];
let resultArr = JSON.parse(JSON.stringify(arr));
let tempArr = [];
for (let i = 0; i < arr[0].length; i++) {
for (let j = 0; j < arr.length; j++) {
tempArr.push(arr[j][i]);
}
if (tempArr.every(item => item === tempArr[0])) {
let index = resultArr[0].findIndex(p => p === tempArr[0]);
resultArr = resultArr.map(val => {
val.splice(index, 1);
return val;
});
}
tempArr = [];
}
console.log(resultArr);
So, based on the above logic the original answer will be below
const array1 = [
[{
checked: false,
id: 13993,
type: "checkbox",
},
{
checked: false,
id: 13995,
type: "label",
},
{
checked: false,
id: 13998,
type: "label",
},
{
checked: false,
id: 13940,
type: "label",
},
],
[{
checked: false,
id: 13993,
type: "checkbox",
},
{
checked: false,
id: 13995,
type: "label",
},
{
checked: false,
id: 13998,
type: "checkbox",
},
{
checked: false,
id: 13940,
type: "label",
},
],
[{
checked: false,
id: 13993,
type: "checkbox",
},
{
checked: false,
id: 13995,
type: "label",
},
{
checked: false,
id: 13998,
type: "checkbox",
},
{
checked: false,
id: 13940,
type: "label",
},
],
[{
checked: false,
id: 13993,
type: "label",
},
{
checked: false,
id: 13995,
type: "label",
},
{
checked: false,
id: 13998,
type: "label",
},
{
checked: false,
id: 13940,
type: "label",
},
]
];
let resultArr = JSON.parse(JSON.stringify(array1));
let tempArr = [];
for (let i = 0; i < array1[0].length; i++) {
for (let j = 0; j < array1.length; j++) {
tempArr.push(array1[j][i]);
}
if (tempArr.every(item => item.type === tempArr[0].type && item.type === 'label')) {
let index = resultArr[0].findIndex(p => p.id === tempArr[0].id);
resultArr = resultArr.map(val => {
val.splice(index, 1);
return val;
});
}
tempArr = [];
}
console.log(resultArr);
[
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 },
],
[
{ id: 2 },
{ id: 2 },
{ id: 3 },
{ id: 5 },
],
]
function createNewArray(arr, n) {
const newArr = [];
arr.forEach(element => {
newArr.push(element[n])
});
return newArr;
}
function getResult() {
const tempArray = [];
for (let index = 0; index < origin[0].length; index++){
const newArray = createNewArray(origin, index).map(e => e.id);
if ([...new Set(newArray)].length > 1) {
tempArray.push(newArray);
}
}
let result = Array(tempArray[0].length).fill([]);
return result.map((item, index) => tempArray.map(e => e[index]));
}
console.log('result', getResult());
Do you mean something like this?
const removeCol = (table, colIndex) => {
table.forEach(row => row.splice(colIndex, 1))
}
removeCol(array1, 0); // To remove column 0 (0-indexed)
removeCol(array1, 1); // To remove column 1 (0-indexed)
Not a perfect solution but to get result as expected :
Filter id's of two 13993,13998
check the id and modify value accordingly
const array1 = [
[{
checked: false,
id: 13993,
type: "checkbox",
},
{
checked: false,
id: 13995,
type: "label",
},
{
checked: false,
id: 13998,
type: "label",
},
{
checked: false,
id: 13940,
type: "label",
},
],
[{
checked: false,
id: 13993,
type: "checkbox",
},
{
checked: false,
id: 13995,
type: "label",
},
{
checked: false,
id: 13998,
type: "checkbox",
},
{
checked: false,
id: 13940,
type: "label",
},
],
[{
checked: false,
id: 13993,
type: "checkbox",
},
{
checked: false,
id: 13995,
type: "label",
},
{
checked: false,
id: 13998,
type: "checkbox",
},
{
checked: false,
id: 13940,
type: "label",
},
],
[{
checked: false,
id: 13993,
type: "label",
},
{
checked: false,
id: 13995,
type: "label",
},
{
checked: false,
id: 13998,
type: "label",
},
{
checked: false,
id: 13940,
type: "label",
},
]
];
let filteredArray = array1.map(x=>x.filter(v=>v.id==13993||v.id==13998)) // 1st step
let result = filteredArray.map(x=>x.filter(v=>v.id==13993?v.type="checkbox":v.type="label")) // 2nd step
//2nd step i guess can be done in much efficient way
console.log(result)

Compare values ​between two object arrays

I have the following scenario:
var arr1 = [{
sys_id: "b717af1adbd0bf00daba4410ba961913",
className: "x_rdbsa_cross_fert_cross_fertilization",
display_field: {display_value: "L190322025", label: "Number", type: "string", value: "L190322025"},
secondary_fields: {display_value: "Waiting for Approval", label: "Status", type: "integer", value: "10"}];
var arr2 = [{approver: null, number: "L190322025-1", country: "Argentina", id: "0567a35adbd0bf00daba4410ba9619d6", state: "Waiting for Approval"}
I want to buy the arr2 number with the arr1 number display_field.display_value
There's an error in your example (see below) so fix that first:
var arr1 = [{
sys_id: "b717af1adbd0bf00daba4410ba961913",
className: "x_rdbsa_cross_fert_cross_fertilization",
display_field: {
display_value: "L190322025",
label: "Number",
type: "string",
value: "L190322025"
},
secondary_fields: {
display_value: "Waiting for Approval",
label: "Status",
type: "integer",
value: "10"
}
}]; // <----you forgot this closing curly brace
var arr2 = [{
approver: null,
number: "L190322025-1",
country: "Argentina",
id: "0567a35adbd0bf00daba4410ba9619d6",
state: "Waiting for Approval"
}]
// Now compare the relevant properties of first object in each array
console.log(arr1[0].display_field.display_value === arr2[0].number) // false

Categories