I am trying to compare 2 nested json objects arrays using lodash. Following example will return true even obj1 and obj2 have different number of objects inside the array.
Basically what I need to do is compare these 2 nested json objects arrays and if the arrays are identical then needs to return true else false
note : obj1 has price element and obj2 has countInStock which should not use to compare
Can anyone help me to solve this?
import _ from "lodash"
var obj1 = [{
"colour": {
"value": "Black",
"label": "Black"
},
"size": {
"value": "M",
"label": "M"
},
"price": "70"
},
{
"colour": {
"value": "Black",
"label": "Black"
},
"size": {
"value": "M",
"label": "M"
},
"price": "70"
},
{
"colour": {
"value": "Silver",
"label": "Silver"
},
"size": {
"value": "S",
"label": "S"
},
"price": "50"
},
{
"colour": {
"value": "Black",
"label": "Black"
},
"size": {
"value": "L",
"label": "L"
},
"price": "130"
}]
var obj2 = [{
"colour": {
"value": "Silver",
"label": "Silver"
},
"size": {
"value": "S",
"label": "S"
},
"countInStock": "3"
},
{
"colour": {
"value": "Black",
"label": "Black"
},
"size": {
"value": "M",
"label": "M"
},
"countInStock": "10"
},
{
"colour": {
"value": "Black",
"label": "Black"
},
"size": {
"value": "L",
"label": "L"
},
"countInStock": "3"
}]
var result = _.isEqual(
_.omit(obj1.sort, ['price']),
_.omit(obj2.sort, ['countInStock'])
);
console.log(result); // true
Related
Currently i have below Array of Objects
const dataClass = [
{
"id": 101,
"class": [
{
"type": "A",
"value": "A-class"
},
{
"type": "B",
"value": "B-class"
},
{
"type": "C",
"value": "C-class"
}
],
"rank": 1
},
{
"id": 102,
"class": [
{
"type": "D",
"value": "D-class"
},
{
"type": "E",
"value": "E-class"
},
{
"type": "F",
"value": "F-class"
}
],
"rank": 2
},
{
"id": 103,
"class": [
{
"type": "G",
"value": "G-class"
},
{
"type": "H",
"value": "H-class"
},
{
"type": "I",
"value": "I-class"
}
],
"rank": 3
}
];
i need to get dataClass object using all value inside the class object, let say i want to get the second object, so i have to search/input "type": "D", "type": "E", and "type": "F".
return array object/object i expect:
[{
"id": 102,
"class": [
{
"type": "D",
"value": "D-class"
},
{
"type": "E",
"value": "E-class"
},
{
"type": "F",
"value": "F-class"
}
],
"rank": 2
}]
I don't find any solution so far, Thanks for any help.
I added one more object with types D, E, F at rank 4
If you want to return all objects that match your filtration, check result1
and if you just wanna return the first object that matches, check result2
const dataClass = [
{
"id": 101,
"class": [
{
"type": "A",
"value": "A-class"
},
{
"type": "B",
"value": "B-class"
},
{
"type": "C",
"value": "C-class"
}
],
"rank": 1
},
{
"id": 102,
"class": [
{
"type": "D",
"value": "D-class"
},
{
"type": "E",
"value": "E-class"
},
{
"type": "F",
"value": "F-class"
}
],
"rank": 2
},
{
"id": 103,
"class": [
{
"type": "G",
"value": "G-class"
},
{
"type": "H",
"value": "H-class"
},
{
"type": "I",
"value": "I-class"
}
],
"rank": 3
},
{
"id": 104,
"class": [
{
"type": "D",
"value": "D-class"
},
{
"type": "E",
"value": "E-class"
},
{
"type": "F",
"value": "F-class"
}
],
"rank": 4
}
];
const expectedValues = ['D', 'E', 'F'];
//use this if you wanna return all objects that match expectedValues
const result1 = dataClass.filter(el => el.class.every(obj => expectedValues.includes(obj.type)));
console.log('all matched Objects => ', result1);
//use this if you wanna return the first object that match expectedValues
const result2 = dataClass.find(el => el.class.every(obj => expectedValues.includes(obj.type)));
console.log('first matched object => ',result2);
Hope this will help,
const dataClass = [
{
"id": 101,
"class": [
{
"type": "A",
"value": "A-class"
},
{
"type": "B",
"value": "B-class"
},
{
"type": "C",
"value": "C-class"
}
],
"rank": 1
},
{
"id": 102,
"class": [
{
"type": "D",
"value": "D-class"
},
{
"type": "E",
"value": "E-class"
},
{
"type": "F",
"value": "F-class"
}
],
"rank": 2
},
{
"id": 103,
"class": [
{
"type": "G",
"value": "G-class"
},
{
"type": "H",
"value": "H-class"
},
{
"type": "I",
"value": "I-class"
}
],
"rank": 3
}
];
const resultArr = [];
for (const ch_arr of dataClass){
for (const class_arr of ch_arr["class"]){
if(["D","E","F"].includes(class_arr["type"])){
resultArr.push(ch_arr);
break;
}
};
};
// resultArr is the expected array
You need find the object inside of class Array so i think using find method is the more readable way to solved it
function findClassByType(value: string) {
return [dataClass.find((obj) => obj.class.find(({ type }) => type.toLocaleLowerCase() === value.toLocaleLowerCase()))];
}
console.log(findClassByType('a'))
I added the toLocaleLowerCase to avoid case sensitive.
let selected_variation = [{
"type": "Capacity",
"value": "512G",
},
{
"type": "Color",
"value": "#000000",
}
]
let attributes = [{
"id": "Color",
"name": "Color",
"type": "swatch",
"items": [{
"displayValue": "Green",
"value": "#44FF03",
"id": "Green"
},
{
"displayValue": "Cyan",
"value": "#03FFF7",
"id": "Cyan"
},
{
"displayValue": "Blue",
"value": "#030BFF",
"id": "Blue"
},
{
"displayValue": "Black",
"value": "#000000",
"id": "Black"
},
{
"displayValue": "White",
"value": "#FFFFFF",
"id": "White"
}
]
},
{
"id": "Capacity",
"name": "Capacity",
"type": "text",
"items": [{
"displayValue": "512G",
"value": "512G",
"id": "512G"
},
{
"displayValue": "1T",
"value": "1T",
"id": "1T"
}
]
}
]
so I have these two arrays one I am creating to track the selected variation of the product from the user there is a bug in it the order of the variation in my created array depends on which order the user clicks on the input fields I need to map my array in the order of the resulted api and the variations are not fixed it actually varies according to the product so my expected output
Output
let selected_variation = [
{"type":"Color","value":"#000000"},
{"type":"Capacity","value":"512G"}
]
the same order the API is following
Maybe you could try this:
const order = attributes.map((attribute) =>
selected_variation.find((v) => v.type === attribute.id)
);
console.log(order)
Based on accepted answer of this question: Javascript - sort array based on another array
const selected_variation = [{
"type": "Capacity",
"value": "512G",
},
{
"type": "Color",
"value": "#000000",
}
]
const attributes = [{
"id": "Color",
"name": "Color",
"type": "swatch",
"items": [{
"displayValue": "Green",
"value": "#44FF03",
"id": "Green"
},
{
"displayValue": "Cyan",
"value": "#03FFF7",
"id": "Cyan"
},
{
"displayValue": "Blue",
"value": "#030BFF",
"id": "Blue"
},
{
"displayValue": "Black",
"value": "#000000",
"id": "Black"
},
{
"displayValue": "White",
"value": "#FFFFFF",
"id": "White"
}
]
},
{
"id": "Capacity",
"name": "Capacity",
"type": "text",
"items": [{
"displayValue": "512G",
"value": "512G",
"id": "512G"
},
{
"displayValue": "1T",
"value": "1T",
"id": "1T"
}
]
}
]
selected_variation.sort((a, b) => {
return attributes.findIndex(attr => attr.id === a.type) - attributes.findIndex(attr => attr.id === b.type);
});
console.log(selected_variation);
But it will work really long if there will be a lot of elements because we must to loop through attributes array twice for each pair again and again. But if we will use a little more memory we can greatly optimize the algorithm. The main idea is to create a dictionary where the keys are ids of attributes and values are they index in attributes array:
const selected_variation = [{
"type": "Capacity",
"value": "512G",
},
{
"type": "Color",
"value": "#000000",
}
]
const attributes = [{
"id": "Color",
"name": "Color",
"type": "swatch",
"items": [{
"displayValue": "Green",
"value": "#44FF03",
"id": "Green"
},
{
"displayValue": "Cyan",
"value": "#03FFF7",
"id": "Cyan"
},
{
"displayValue": "Blue",
"value": "#030BFF",
"id": "Blue"
},
{
"displayValue": "Black",
"value": "#000000",
"id": "Black"
},
{
"displayValue": "White",
"value": "#FFFFFF",
"id": "White"
}
]
},
{
"id": "Capacity",
"name": "Capacity",
"type": "text",
"items": [{
"displayValue": "512G",
"value": "512G",
"id": "512G"
},
{
"displayValue": "1T",
"value": "1T",
"id": "1T"
}
]
}
]
const attributesMap = new Map();
attributes.forEach((attribute, index) => attributesMap.set(attribute.id, index))
selected_variation.sort((a, b) => attributesMap.get(a.type) - attributesMap.get(b.type));
console.log(selected_variation);
I have JSON that looks like this:
{
"primary": {
"value": "#0093c1",
"type": "color"
},
"background": {
"value": "#f2f2f2",
"type": "color"
},
"foreground": {
"value": "#000000",
"type": "color"
},
"secondary": {
"value": "#32c100",
"type": "color"
},
"alert": {
"value": "#c10000",
"type": "color"
}
}
How do I first check if each has a type and if so, then remove all type key/value pairs no matter how nested they might be?
try this
Object.keys(obj).forEach((prop) => {
delete obj[prop].type;
});
result
{
"primary": {
"value": "#0093c1"
},
"background": {
"value": "#f2f2f2"
},
"foreground": {
"value": "#000000"
},
"secondary": {
"value": "#32c100"
},
"alert": {
"value": "#c10000"
}
}
I have created a Javascript array that I need to reformat into Json so that I can display it in a table.
I am trying to take the following javascript array:
[
{
"name": "ticker",
"value": "V"
},
{
"name": 5,
"value": -0.09453565931246788
},
{
"name": 10,
"value": -0.08185562540645996
},
{
"name": 90,
"value": -0.1023591207807445
},
{
"name": 120,
"value": -0.03745328055393815
},
{
"name": 250,
"value": 0.13101799630844946
}
]
And transform it into:
const myTableData = [
{"name": "ticker", "value": V},
{"name": "5", "value": -0.09453565931246788},
{"name": "10", "value": -0.08185562540645996},
{"name": "90", "value": -0.1023591207807445},
{"name": "120", "value": -0.03745328055393815},
{"name": "250", "value": 0.13101799630844946}
];
How can I do this?
Just use JSON.stringify
var myArray = [
{
"name": "ticker",
"value": "V"
},
{
"name": 5,
"value": -0.09453565931246788
},
{
"name": 10,
"value": -0.08185562540645996
},
{
"name": 90,
"value": -0.1023591207807445
},
{
"name": 120,
"value": -0.03745328055393815
},
{
"name": 250,
"value": 0.13101799630844946
}
];
var myJsonString = JSON.stringify(myArray);
console.log(myJsonString);
I am converting the object to tree node format using the below method
function getNodes(object) {
return Object
.entries(object)
.map(([key, value]) => value && typeof value === 'object' ?
{
value: key + value,
label: key,
children: getNodes(value)
} :
{
value: key + value,
label: key
}
);
}
The sample object is:
var object = {
"income-array": [{
"income": {
"id": "1234",
"currency": "dollar",
"details": {
"individual-income": [{
"name": "abcd",
"income": 100
}, {
"name": "xyz",
"income": 500
}]
}
}
}]
}
I am getting this result:
[{
"value": "income-array[object Object]",
"label": "income-array",
"children": [{
"value": "0[object Object]",
"label": "0",
"children": [{
"value": "income[object Object]",
"label": "income",
"children": [{
"value": "id1234",
"label": "id"
}, {
"value": "currencydollar",
"label": "currency"
}, {
"value": "details[object Object]",
"label": "details",
"children": [{
"value": "individual-income[object Object],[object Object]",
"label": "individual-income",
"children": [{
"value": "0[object Object]",
"label": "0",
"children": [{
"value": "nameabcd",
"label": "name"
}, {
"value": "income100",
"label": "income"
}]
}, {
"value": "1[object Object]",
"label": "1",
"children": [{
"value": "namexyz",
"label": "name"
}, {
"value": "income500",
"label": "income"
}]
}]
}]
}]
}]
}]
}]
I want to get the value property path from root to a particular node like the below. I am confused with how to append step by step path to value.
[{
"value": "income-array",
"label": "income-array",
"children": [{
"value": "['income-array'][0]",
"label": "0",
"children": [{
"value": "['income-array'][0]['income']",
"label": "income",
"children": [{
"value": "['income-array'][0]['income']['id']",
"label": "id"
}, {
"value": "['income-array'][0]['income']['currencydollar']",
"label": "currency"
}, {
"value": "['income-array'][0]['income']['details']",
"label": "details",
"children": [{
"value": "['income-array'][0]['income']['details']['individual-income']",
"label": "individual-income",
"children": [{
"value": "['income-array'][0]['income']['details']['individual-income'][0]",
"label": "0",
"children": [{
"value": "['income-array'][0]['income']['details']['individual-income'][0]['name']",
"label": "name"
}, {
"value": "['income-array'][0]['income']['details']['individual-income'][0]['income']",
"label": "income"
}]
}, {
"value": "['income-array'][0]['income']['details']['individual-income'][1]",
"label": "1",
"children": [{
"value": "['income-array'][0]['income']['details']['individual-income'][1]['name']",
"label": "name"
}, {
"value": "['income-array'][0]['income']['details']['individual-income'][1]['income']",
"label": "income"
}]
}]
}]
}]
}]
}]
}]
Can you please guide me how to resolve this? Thanks
The outer function needs to pass its own current absolute path (which is value in your code) to the inner function,
in order to let the inner function know the previous paths.
Notice the parentPath='' parameter and children: getNodes(value, currentPath) below
function getNodes(object, parentPath = "") {
return Object.entries(object).map(([key, value]) => {
const currentPath = parentPath + `[${key}]`;
return value && typeof value === "object"
? {
value: currentPath,
label: key,
children: getNodes(value, currentPath),
}
: {
value: currentPath,
label: key,
};
});
}
After that, run getNodes(object) in the browser and you will get a result like this.
[
{
"value": "[income-array]",
"label": "income-array",
"children": [
{
"value": "[income-array][0]",
"label": "0",
"children": [
{
"value": "[income-array][0][income]",
"label": "income",
"children": [
{
"value": "[income-array][0][income][id]",
"label": "id"
},
{
"value": "[income-array][0][income][currency]",
"label": "currency"
},
{
"value": "[income-array][0][income][details]",
"label": "details",
"children": [
{
"value": "[income-array][0][income][details][individual-income]",
"label": "individual-income",
"children": [
{
"value": "[income-array][0][income][details][individual-income][0]",
"label": "0",
"children": [
{
"value": "[income-array][0][income][details][individual-income][0][name]",
"label": "name"
},
{
"value": "[income-array][0][income][details][individual-income][0][income]",
"label": "income"
}
]
},
{
"value": "[income-array][0][income][details][individual-income][1]",
"label": "1",
"children": [
{
"value": "[income-array][0][income][details][individual-income][1][name]",
"label": "name"
},
{
"value": "[income-array][0][income][details][individual-income][1][income]",
"label": "income"
}
]
}
]
}
]
}
]
}
]
}
]
}
]