How to know array contents are empty - arrays

Lets say I have array like this :
[
{
"id" : "1"
"name": "David",
"age": "20"
},
{
"id" : "2"
"name": "",
"age": "18"
},
{
"id" : "3"
"name": "Micheal",
"age": "25"
},
{
"id" : "4"
"name": "Wonder Women",
"age": "20"
},
{
"id" : "5"
"name": "Clark",
"age": ""
}
]
Some of the contents are empty. How to write the condition if "age" is null and "name" is null.

You can filter the array and then use it where you need:
const myFilteredArray = arr.filter(item => {
return item.name !== null && item.age !== null
})
// use myFilteredArray in your code.

As your request is not definitive, I'm assuming you want the person elements that satisfy your criteria in a new array, called personsWithoutNameAndAge.
You can achieve this very elegantly, using functional programming:
const personsWithoutNameAndAge = persons.filter(person => !person.name && !person.age)
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
The function we provide the filter function (the argument passed to it) only passes the test (returns true) if both person.name and person.age are falsy. Empty string, undefined, and null are all falsy and so the function will successfully work with any of these values representing 'null'.
Hope this helps!

Related

How do I update all of a specific element in an array in mongoDB?

I have the following data:
{
"name": "tom",
"songs": [
{ "songname": "hello", "day": "20" },
{ "songname": "goodbye", "day": "25" },
{ "songname": "morning", "day": "15" }],
"solo": "yes"
}
I want to increment the day of each of the songs in the array by 2 for the person with the name tom. I figured using $inc such as
db.collection.update({ "name": "tom" }, { "$inc": { "songs.day": 2 } })
would work but it doesnt work. I get the error "errmsg" : "The positional operator did not find the match needed from the query."
first of all, for $inc to work, you need to store your day values as numbers/ints. $inc doesn't work on strings.
then simply use the all positional operator $[] like so:
db.collection.update(
{ "name": "tom" },
{ "$inc": { "songs.$[].day": 2 } }
)

CastError: Cast to ObjectId failed for value 'xxx' at path "_id"

I have an array in request as:
{
"acceptedBookings": [
{
"id": "e1f66d7a852986709f665c3",
"Date": "2020-02-04T05:03:25.332Z"
}
]
}
I want to update the "date" for every "id". However If I search as
await Booking.findById( acceptedBookings[0].id ) or
await Booking.findOne({_id : acceptedBookings[0].id})
It does not give a response
You're accessing wrong member, what you want is:
let's assume your map is something like
const acceptedBookings = {
"accepted": [{
"id": "e1f66d7a852986709f665c3",
"Date": "2020-02-04T05:03:25.332Z"
},
{
"id": "i123",
"Date": "2020-02-04T05:03:25.332Z"
},
{
"id": "i123",
"Date": "2020-02-04T05:03:25.332Z"
}
]
};
console.log(acceptedBookings.accepted[0].id); // e1f66d7a852986709f665c3
console.log(acceptedBookings.accepted[1].id); // i123
await Booking.findById( acceptedBookings.accepted[0].id ) //should work fine
Remember the object you've created that is not an array it's map/object with a key: value pair
thus get the right array/element first then access it's members

JSON schema different for first row and different for remaining rows

my problem statement is :
consider a a list of 15 rows, all rows should have 5 keys. However only the 0th row will have 4 keys. But all the remaining rows will have all the 5 keys.
I want to validate this again my response. Does first and other keyword really exist.
I found this here Correct JSON Schema for an array of items of different type
Example schema
{
"type": "array",
"items": {
"oneOf": [
{
"first": [{
"type": "object",
"required": ["state"],
"properties":{
"state":{
"type":"string"
}
}
}]
},
{
"other": [{
"type": "object",
"required": ["state", "zip"],
"properties":{
"state":{
"type":"string"
},
"zip":{
"type":"string"
}
}
}]
}
]
}
}
First things first: what do you want to achieve with following schema definition?
"first" : [ { ...schema... } ]
As to your problem statement, I am not sure, what you want to achieve:
Schema that allows first array item to be an object with 4 keys, while all other items should have 5 keys?
Schema, that allows only array items=object with 5 keys and will reject a JSON, which does have 4 keys in first item
Could you please rephrase your question to make it more clear? I did some solution basing on assumptions, but it would be good if you could confirm my understanding.
Required reading
Please read first through:
http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.4.1
If "items" is an array of schemas, validation succeeds if each element
of the instance validates against the schema at the same position, if
any.
plus https://stackoverflow.com/a/52758108/2811843 on above topic
https://json-schema.org/understanding-json-schema/reference/array.html#length
https://json-schema.org/understanding-json-schema/reference/array.html#tuple-validation
and https://json-schema.org/understanding-json-schema/reference/array.html in general
as well as
https://json-schema.org/understanding-json-schema/reference/object.html#property-names
https://json-schema.org/understanding-json-schema/reference/object.html#size
and https://json-schema.org/understanding-json-schema/reference/object.html in general.
Possible solution
After looking at sample schema I will rephrase problem statement making some wild assumptions you want a schema, that allows an array of items, where item = object. First item could have 4 keys, while all other items must have 5 keys.
I need a JSON schema that will describe an array of objects, where
first object always has 4 keys/properties, while all remaining objects
do have 5 keys/properties.
Additionally, there is always at least first item in array (containing 4 keys) and there can be up to X other
objects (containing 5 keys) in array.
Go for Tuple-typing and array of objects. Thus you might exactly check that first item (object) has exactly 4 properties and define the schema for the rest of them.
First, full working schema (with comments inside). The "examples" section contains examples of arrays to illustrate the logic, only last 3 will be valid against schema.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"$comment" : "This is an array, where first item must be an object with at least 4 properties and one property named \"state\" and can contain minimum 1 and maximum of 3 items",
"minItems" : 1,
"maxItems" : 3,
"items": [
{
"type": "object",
"minProperties" : 4,
"required" : ["state"],
}
],
"additionalItems" : {
"$comment" : "Any additional item in this array must be an object with at least 5 keys and two of them must be \"state\" and \"zip\".",
"type" : "object",
"minProperties" : 5,
"required" : ["state", "zip"],
},
"examples" : [
[
{
"key1" : "1",
"key2" : "2",
"key3" : "3",
"state" : "some state",
},
{},
{}
],
[
{
"key1" : "1",
"key2" : "2",
"key3" : "3",
"state" : "some state",
},
{
"key1" : "1",
"key2" : "2",
"key3" : "3",
"state" : "some state",
"zip" : "12345"
},
{
"key1" : "1",
"key2" : "2",
"key3" : "3",
"state" : "some state",
}
],
[
{
"key1" : "1",
"key2" : "2",
"key3" : "3",
"state" : "some state",
},
{
"key1" : "1",
"key2" : "2",
"key3" : "3",
"state" : "some state",
"zip" : "12345"
},
{
"key1" : "1",
"key2" : "2",
"key3" : "3",
"state" : "some state",
"zip" : "54321"
},
{
"key1" : "1",
"key2" : "2",
"key3" : "3",
"state" : "some state",
"zip" : "54321"
}
],
[],
[
{
"key1" : "1",
"key2" : "2",
"key3" : "3",
"state" : "some state",
},
{
"key1" : "1",
"key2" : "2",
"key3" : "3",
"state" : "some state",
"zip" : "12345"
},
{
"key1" : "1",
"key2" : "2",
"key3" : "3",
"state" : "some state",
"zip" : "54321"
},
],
[
{
"key1" : "1",
"key2" : "2",
"key3" : "3",
"state" : "some state",
},
],
[
{
"key1" : "1",
"key2" : "2",
"key3" : "3",
"state" : "some state",
},
{
"key1" : "1",
"key2" : "2",
"key3" : "3",
"state" : "some state",
"zip" : "12345"
},
]
]
}
So, step by step:
"type": "array",
"minItems" : 1,
"maxItems" : 3,
an JSON which is an array with minimum 1 item, maximum 3 items, will be ok. If you don't define "minItems" value, the empty array would pass validation against schema.
"items": [
{
"type": "object",
"minProperties" : 4,
"required" : ["state"],
}
],
This is the Tuple magic - a finite, ordered list of elements (sequence). Yep, maths has it's saying. By using "items" : [ ... ] instead of { ... } you fall into quoted above section of JSON Schema Validation spec (http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.4.1 ).
Above basically says: This is an array, where first item must be an object with at least 4 keys and one of those keys must be "state".
Ok, last but not least:
"additionalItems" : {
"$comment" : "Any additional item in this array must be an object with at least 5 keys and two of them must be \"state\" and \"zip\".",
"type" : "object",
"minProperties" : 5,
"required" : ["state", "zip"],
}
By this I said:
in this array (which must have first item an object with 4 keys and one of those keys is "state" and oh, by the way, an array must have at least 1 item and tops 3 items) you can have additional items on top of the the ones already defined in "items" section. Each such additional item must be an object with at least 5 keys, out of which two must be "state" and "zip".
Does it solve your issue?

Get array key to remove an array based on that array object

New question, so this is the array
[
0: {
"id" : "3"
"name": "David",
"age": "20"
},
1: {
"id" : "6"
"name": "",
"age": "18"
},
2: {
"id" : "8"
"name": "Micheal",
"age": "25"
},
3: {
"id" : "9"
"name": "Wonder Women",
"age": "20"
},
4: {
"id" : "12"
"name": "Clark",
"age": ""
}
]
How to delete based on id when I click a button? In my app have a delete button to delete this array. I think it need to get array key in order to delete the array.
For example: I can get the id=8, but how can i get array key 2 to delete number 2 array?
If you don't understand, please welcome to comment. Thanks.
array.filter((obj) => {
if (obj.id != yourId){
return obj;
}
})
and don't forget all commas in your objects in array. (after id)
if you want to directly manipulate the contents of an array instead of returning new array, you can try this
let index = array.findIndex(obj => obj.id == objIdToDelete)
if(index != -1) { array.splice(index, 1) }
check Array.prototype.splice() to know more
Suppose your array is like:
arr = [
{"id":"3","name":"Clark"},
{"id":"6","name":"David"},
{"id":"8","name":"Miche"}
];
id = 6;
arr = $.grep(arr, function(data, index) {
return data.id != id
});
Now finally this will return array with removing record of id=6
Suppose your array was stored in obj, you can use lodash function remove to remove an item in an array in the following way.
_.remove(obj, function(currentObject) {
return currentObject.id == "8";
});
Which will remove the item '2' containing '8' from your array

How to modify a complex JSON Object in using Immutable

I have below JSON and wanted to update the value depending on Aid, Bid and Cid using Immutable.js
e.g.
Below input provided.
Aid= A, Bid = 1, Cid= 4, NewValue = 'FOUR'
If above input is provided the value "One" needs to be changed to "FOUR"
let sampleJson = {
Aid: 'A', detail:"sample", list: [
{
"Bid": "1",
"group": [
{
"name": "Group A",
"Cid": "4",
"value": "One"
},
{
"name": "Group A",
"Cid": "41",
"value": "1"
},
]
},
{
"Bid": "2",
"group": [
{
"name": "Group A",
"Cid": "4",
"value": "1"
},
{
"name": "Group A",
"Cid": "4",
"value": "1"
},
]
};
I was able to access the value using below code. How can i return the entire JSON with updated value?
let variale = Immutable.fromJS(sampleJson).
getIn(['list']).
find(allocation => allocation.get("Bid") === "1").
getIn(['group']).
find(fun => fun.get("Cid") === "4").set('value',"FOUR");
Anyone has any suggestions on how to resolve this problem?
I think you can try to do this like so:
let immutable = Immutable.fromJS(sampleJson);
immutable = immutable.setIn(['list', 0, 'group', 0, 'value'], 'FOUR');
This monstrosity is how I would do it:
const newData = originalData.update('list', list => {
const itemIndex = list.findIndex(item => item.get('Bid') === '2');
return list.update(itemIndex, listItem => {
return listItem.update('group', groupList => {
const groupIndex = list.findIndex(group => group.get('Cid') === '4');
return groupList.update(groupIndex, group => {
return group.set('value', 'FOUR');
});
});
});
});
https://jsbin.com/latupo/7/edit?html,js,console
Personally I stopped using Immutable, I always found it a bit painful (not to mention those docs!). I now use redux and good old cloning to not mutate state. Less performant in theory but if you've got nothing that runs over a few milliseconds anyway, save yourself the trouble...

Resources