How do I find the existence of a value in JSON - javascript

Say I wanted to check if Mango_EA existed. How would I do that in Node JS.
{
"selection1": [
{
"name": "ClashOnGan"
},
{
"name": "JoblessGarrett"
},
{
"name": "FemmeFatale"
},
{
"name": "Mango_EA"
}
]
}

obj.selection1.some(x => x.name === "Mango_EA")
In English,
Within the array given by obj.selection1, is there some element x which satisfies the condition that the name property of x is equal to "Mango_EA".

Related

Search if a String has a subset string present in array of object javascript

Looking for the optimal solution to find a string inside an array of objects.
Let's say I have a variable that holds a result which I get from an API call
let result = "485178485451478"
I have to search the above result in the below array of objects & see if the substring in the array matches the result. If the result matches I simply want to return true.
const arrayCode = [
{
"code": "2150"
},
{
"code": "4857"
},
{
"code": "5046"
},
{
"code": "4851"
},
{
"code": "4154"
},
{
"code": "9654"
},
{
"code": "1254"
},
{
"code": "9562"
},
{
"code": "1457"
},
{
"code": "6479"
}]
So here in the above problem if I write a code, it should return me an index of 3.
Below is the basic code which I wrote to get the solution. But what if the array length is too long? Looking for the optimal solution. Thanks
Below is the code:
let result = "485178485451478"
let index = 0
for(let i= 0; i< arrayCode.length;i++){
let flag = result.indexOf(arrayCode[i].code);
if(flag===0){
index = i;
break;
}
}
console.log(index)
You can simply achieve this requirement with a single line of code with the help of Array.some() method along with String.indexOf()
Live Demo :
let result = "485178485451478";
const arrayCode = [
{
"code": "2150"
},
{
"code": "4857"
},
{
"code": "5046"
},
{
"code": "4851"
},
{
"code": "4154"
},
{
"code": "9654"
},
{
"code": "1254"
},
{
"code": "9562"
},
{
"code": "1457"
},
{
"code": "6479"
}
];
const res = arrayCode.some(({ code }) => result.indexOf(code) !== -1);
console.log(res);
The some function will iterate only until it finds the first occurrence, so you could use along with the includes function:
const included = (element) => result.includes(element.code);
console.log(arrayCode.some(included));
here is What I would do:
let index = 0
arrayCode.forEach((e, indx) => {if(result.indexOf(e.code) == 0)index = indx;});
console.log(index)
Hope to help!

Find an object and its parent by a property value of a nested object with Javascript

Given the following sample JSON (stringified from the corresponding JavaScript object), I need to extract this information:
Find the object in persons which has the reference = 2.
If a person with this reference was found, get the name of the person's parent element (here: "B").
In the end, I need to build a new object looking similar to this. This won't be problematic but I'm struggling with how to extract these objects from the source. I tried different approaches with find(), map(), flatMap() and filter() but none of them really worked.
{
companyName: "B",
person: {
"reference": 2,
"name": "Bob"
}
}
Source
{
"root": [
{
"companies": [
{
"name": "A",
"persons": [
{
"reference": 1,
"name": "Alex"
}
]
}
]
},
{
"companies": [
{
"name": "B",
"persons": [
{
"reference": 2,
"name": "Bob"
},
{
"reference": 3,
"name": "Charles"
}
]
}
]
}
]
}
If you're just interested in the name of the company you can find it using:
const reference = 2;
const company = data.root.flatMap(item => item.companies)
.find(company => company.persons.some(person => person.reference === reference));
const companyName = company?.name;
// or if you cannot use optional chaining
const companyName = (company || {}).name;
In data.root.flatMap(item => item.companies) we iterate through all items in root, for each item we select its companies property. Since we don't want a nested array we use flatMap() to flatten the result by 1 level. This leaves us with an array of companies.
After that we'll call find() on the companies array, since we are looking for a specific company name. The criteria of the company is that some() (1 or more) of the persons should match the provided reference. If no match is found null will be returned (from find()).
We then take the find() result (company) and navigate to the name via optional chaining ?.. This will return the name of the company if present, or undefined if company is null
You can use array.reduce here
let data = JSON.parse(`{
"root": [
{
"companies": [
{
"name": "A",
"persons": [
{
"reference": 1,
"name": "Alex"
}
]
}
]
},
{
"companies": [
{
"name": "B",
"persons": [
{
"reference": 2,
"name": "Bob"
},
{
"reference": 3,
"name": "Charles"
}
]
}
]
}
]
}`)
// GET ALL THE COMPANIES DATA
let companies = data.root.reduce(
(prevValue, currValue) => {
prevValue.push(...currValue.companies)
return prevValue
},
[]
)
// FIND AND CREATE EXPECTED RESULT SET
let results = companies.reduce(
(prevValue, currValue) => {
// loop inside a loop, mind it
let refPerson = currValue.persons.find((item)=> item.reference == 2)
if(refPerson){
prevValue.push({
companyName: currValue.name,
person: refPerson
})
}
return prevValue
},
[]
)
console.log(results)

codition statement empty or not empty

Need help to see if the array is empty or not.
what are the condition block for this?
empty array look like this:
[
{
"readTime": "2019-09-09T15:20:44.648599Z"
}
]
not empty array look like this:
[
{
"document": {
"name": "projects/warrenty-MdBQxhFSQF11ZKImqL",
"fields": {
"plate": {
"stringValue": "AW69176"
"createDate": {
"timestampValue": "2019-08-22T21:08:42.563Z"
},
"product": {
"stringValue": "Paint"
},
"exp_date": {
"timestampValue": "2026-08-22T21:08:18Z"
}
},
"createTime": "2019-08-22T21:09:19.972639Z",
"updateTime": "2019-09-09T11:33:27.134588Z"
},
"readTime": "2019-09-09T15:19:49.433613Z"
},
]
From the look of your JSON you can just check if each object's 'document' property exists.
for (var i = 0; i < array.length; i++){
if (array[i].document){
//exists
}
else { //doesn't exist}
}
You can loop through the array using forEach and can use hasOwnProperty to check if the object have any key by name document
let data = [{
"document": {
"name": "projects/warrenty-MdBQxhFSQF11ZKImqL",
"fields": {
"plate": {
"stringValue": "AW69176",
"createDate": {
"timestampValue": "2019-08-22T21:08:42.563Z"
},
"product": {
"stringValue": "Paint"
},
"exp_date": {
"timestampValue": "2026-08-22T21:08:18Z"
}
},
"createTime": "2019-08-22T21:09:19.972639Z",
"updateTime": "2019-09-09T11:33:27.134588Z"
},
"readTime": "2019-09-09T15:19:49.433613Z"
}
}, {
"readTime": "2019-09-09T15:19:49.433613Z"
}]
data.forEach((e, index) => {
if (e.hasOwnProperty('document')) {
console.log(`Object at index ${index} has document key`)
} else {
console.log(`Object at index ${index} does not have document key`)
}
})
The "empty array" as you call it is not really empty as it contains an object.
But I think what you want to do is figure out whether the array contains an object with the structure of the second array.
In order to check whether your array is "empty" as you call it, you can check wether your object has a property "document" or not.
function isEmpty(array){
var object = array[0];
return !object.hasOwnProperty('document');
}
This function will return true when your array is "empty", and false when it is not.

How to find and replace value in JSON?

I have an object like this:
{
"responses": {
"firstKey": {
"items": {
"name": "test name one"
}
},
"anotherKey": {
"items": {
"name": "test name two"
}
},
"oneMoreKey": {
"items": {
"name": "John"
}
}
}
}
I need to find all 'name' keys and replace its value only if it starts with 'test name' then return new JSON object:
{
"responses": {
"firstKey": {
"items": {
"name": "N/A"
}
},
"anotherKey": {
"items": {
"name": "N/A"
}
},
"oneMoreKey": {
"items": {
"name": "John"
}
}
}
}
The problem is that the keys are not consistent through the objects, i.e. 'firstKey', 'secondKey'... I tried ForEach but it seems to be too cumbersome... So I need either lodash or vanila JavaScript to replace the values.
The javascript object should be iterated and then each value of name can be checked and replaced. There are checks such as hasOwnProperty() that can be used to make sure you are not iterating objects that are missing "items" or "name" for better error handling.
var data = {
"responses": {
"firstKey": {
"items": {
"name": "test name one"
}
},
"anotherKey": {
"items": {
"name": "test name two"
}
},
"oneMoreKey": {
"items": {
"name": "John"
}
}
}
};
Given the JSON above you can use a simple for statement to iterate and then check each name for some value and replace.
for(var key in data.responses){
if ((data.responses[key].items.name).match(/test name/)){
data.responses[key].items.name = "N/A";
}
}
To check your replacements you can log data to the console.
console.log(JSON.stringify(data));
It can also be done during parsing :
var json = `{
"responses": {
"firstKey": {
"items": {
"name": "test name one"
}
},
"anotherKey": {
"items": {
"name": "test name two"
}
},
"oneMoreKey": {
"items": {
"name": "John"
}
}
}
}`
var obj = JSON.parse(json, (k, v) => k == 'name' && /^test name/.test(v) ? 'N/A' : v)
console.log( obj )
A javascript object is for all intents and purposes a tree — though it can be, and may well be, a directed graph — that quite possibly may be cyclic meaning a node in the graph points back to own of its own parents. Following a cycle can result in never-ending recursion or loop.
You want to use something like traverse to do what you're talking about. It takes care of all the stuff that makes traversing a graph hassle — dealing with cycles in the graph and the like.
https://www.npmjs.com/package/traverse
https://github.com/substack/js-traverse
const traverse = require('traverse');
. . .
var scrubbed = traverse(obj).map( function(value) {
const isTestName = this.key === 'name'
&& value
&& /^test name/i.test(value)
;
if (isTestName) {
this.update('N/A');
}
});
NOTE: The callback function given to travese can't be an arrow function (() => {...} as that function's this context is the traverse context for the current node being inspected.
That traverse context also gives you access to the entire path from the root down to the current node, along with an upward link to the parent node's traverse context.
Do something like this. Convert to string replace using regex (add key to regex as well) and then convert back.
var data = {
"responses": {
"firstKey": {
"items": {
"name": "test name one"
}
},
"anotherKey": {
"items": {
"name": "test name two"
}
},
"oneMoreKey": {
"items": {
"name": "John"
}
}
}
};
var originalMsg = JSON.stringify(data);
console.log(data)
console.log(originalMsg)
var updatedMsg = originalMsg.replace(/test name [a-z]*/g, "N/A");
console.log(updatedMsg)
var newObj = JSON.parse(updatedMsg);
console.log(newObj);

cannot update an array of elements via a 2d iteration

I have two arrays of object, the first array (printerChart, around 80 elements) is made of the following type of objects:
[{
printerBrand: 'Mutoh',
printerModel: 'VJ 1204G',
headsBrand: 'Epson',
headType: '',
compatibilty: [
'EDX',
'DT8',
'DT8-Pro',
'ECH',
],
},
....
]
The second array (items, around 500 elements) is made of the following type of objects:
[
{
"customData": {
"brand": {
"value": {
"type": "string",
"content": "hp"
},
"key": "brand"
},
"printer": {
"value": {
"type": "string",
"content": "c4280"
},
"key": "printer"
}
},
"name": "DT8 XLXL",
"image": {
"id": "zLaDHrgbarhFSnXAK",
"url": "https://xxxxxxx.net/images/xxxxxx.jpg"
},
"brandId": "xxxxx",
"companyId": "xxxx",
"createdAt": "2018-03-26T14:39:47.326Z",
"updatedAt": "2018-04-09T14:31:38.169Z",
"points": 60,
"id": "dq2Zezwm4nHr8FhEN"
},
...
]
What I want to do is to iterate via the second array and, if the part of the name of an item (i.e. DT8) is included in an element of the array 'compatibility' of the first array, I would like to include a new properties to it from the element of the first array: printerBrand. I have tried but somehow the iteration doesn't take place correctly. This is what I tried:
items.forEach((item) => {
printerChart.forEach((printer) => {
if (printer.compatibilty.some(compatibleElem => (
item.name.includes(compatibleElem)))) {
item.printerBrand = printer.printerBrand;
} else {
item.printerBrand = '';
}
});
});
What am I doing wrong?
You do
items.items.forEach(...)
Shouldn't you be doing
items.forEach(...)
?
I suggest to initialize item.printerBrand with an empty string and use a nested approach of some for getting a brand and to exit the loops, if found.
This prevents to get an empty string even if there is a brand to assign.
items.forEach((item) => {
item.printerBrand = '';
printerChart.some(printer => {
if (printer.compatibilty.some(compatibleElem => item.name.includes(compatibleElem))) {
item.printerBrand = printer.printerBrand;
return true;
}
});
});

Categories

Resources