How to remove an element from a json with ruby? - arrays

For this json structs:
{
"a_path": {
"b_path": [
{
"id": 1,
"name": "a"
},
{
"id": 2,
"name": "b"
}
]
}
}
Want to remove id element as:
{
"a_path": {
"b_path": [
{
"name": "a"
},
{
"name": "b"
}
]
}
}
Is there a good way? I have tried:
$json_data = JSON.parse(response)["b_path"][0].delete("id")
But got this result:
"a_path": "1"

Even if .delete would return the mutated hash (which it doesn't, it returns the deleted value), you are assigning $json_data = JSON.parse(response)["b_path"][0].
Just assign the base hash, and mutate it in a loop with .each.
json_data = JSON.parse(response)
json_data['a_path']['b_path'].each { |h| h.delete('id') }
json_data
# => the expected hash

Try the .delete method. It shoud return you the mutated hash but in actual it returns the deleted value. So only way is you need to assign the base hash and mutate it in a loop and call .delete within that

Related

How can i merge two array data in react native?

i want fetch 2 data and push array, then merge this two data, who can help me?
My first data example;
{
"experts": [
{
"id": 1,
"name": "XXXXX",
"integration_id": "1",
},
{
"id": 243,
"name": "YYYY",
"integration_id": "2",
},] }
My Second data example https://xxx/api/?staff={integration_id}
{
"uzmanlar": [
{
"id": "1",
"ad_soyad": "xxx",
"pic": "117-k-xxx.jpg",
}
],
}
i want foreach first data array to second data merge. i want print picture screen
const arr1 = res.exprts;
const arr2 = res.uzmanlar;
Array.prototype.push.apply(arr1, arr2);
console.log(arr1) // final merge result would be in arr1
you can try this...
You can achieve this using the ... Spread Syntax:
const array = [...obj1["experts"], ...obj1["uzmanlar"]]
This creates a new array including all elements of the first and second array.

Reference value from positional element in array in update

Suppose I have a document that looks like this:
{
"id": 1,
"entries": [
{
"id": 100,
"urls": {
"a": "url-a",
"b": "url-b",
"c": "url-c"
},
"revisions": []
}
]
}
I am trying to add a new object to the revisions array that contains its own urls field. Two of the fields should be copied from the entry's urls, while the last one will be new. The result should look like this:
{
"id": 1,
"entries": [
{
"id": 100,
"urls": {
"a": "url-a",
"b": "url-b",
"c": "url-c"
},
"revisions": [
{
"id": 1000,
"urls": {
"a": "url-a", <-- copied
"b": "url-b", <-- copied
"c": "some-new-url" <-- new
}
}
]
}
]
}
I am on MongoDB 4.2+, so I know I can use $property on the update query to reference values. However, this does not seem to be working as I expect:
collection.updateOne(
{
id: 1,
"enntries.id": 100
},
{
$push: {
"entries.$.revisions": {
id: 1000,
urls: {
"a": "$entries.$.urls.a",
"b": "$entries.$.urls.b",
"c": "some-new-url"
}
}
}
}
);
The element gets added to the array, but all I see for the url values is the literal $entries.$.urls.a. value I suspect the issue is with combining the reference with selecting a specific positional array element. I have also tried using $($entries.$.urls.a), with the same result.
How can I make this work?
Starting from MongoDB version >= 4.2 you can use aggregation pipeline in updates which means your update part of query will be wrapped in [] where you can take advantage of executing aggregation in query & also use existing field values in updates.
Issue :
Since you've not wrapped update part in [] to say it's an aggregation pipeline, .updateOne() is considering "$entries.$.urls.a" as a string. I believe you'll not be able to use $ positional operator in updates which use aggregation pipeline.
Try below query which uses aggregation pipeline :
collection.updateOne(
{
id: 1,
"entries.id": 100 /** "entries.id" is optional but much needed to avoid execution of below aggregation for doc where `id :1` but no `"entries.id": 100` */,
}
[
{
$set: {
entries: {
$map: { // aggregation operator `map` iterate over array & creates new array with values.
input: "$entries",
in: {
$cond: [
{ $eq: ["$$this.id", 100] }, // `$$this` is current object in array iteration, if condition is true do below functionality for that object else return same object as is to array being created.
{
$mergeObjects: [
"$$this",
{
revisions: { $concatArrays: [ "$$this.revisions", [{ id: 1000, urls: { a: "$$this.urls.a", b: "$$this.urls.b", c: "some-new-url" } } ]] }
}
]
},
"$$this" // Returning same object as condition is not met.
]
}
}
}
}
}
]
);
$mergeObjects will replace existing revisions field in $$this (current) object with value of { $concatArrays: [ "$$this.revisions", { id: 1000, urls: { a: "$$this.urls.a", b: "$$this.urls.b", c: "some-new-url" } } ] }.
From the above field name revisions and as it being an array I've assumed there will multiple objects in that field & So we're using $concatArrays operator to push new objects into revisions array of particular entires object.
In any case, if your revisions array field does only contain one object make it as an object instead of array Or you can keep it as an array & use below query - We've removed $concatArrays cause we don't need to merge new object to existing revisions array as we'll only have one object every-time.
collection.update(
{
id: 1,
"entries.id": 100
}
[
{
$set: {
entries: {
$map: {
input: "$entries",
in: {
$cond: [
{ $eq: ["$$this.id", 100] },
{
$mergeObjects: [
"$$this",
{
revisions: [ { id: 1000, urls: { a: "$$this.urls.a", b: "$$this.urls.b", c: "some-new-url" } } ]
}
]
},
"$$this"
]
}
}
}
}
}
]
);
Test : Test your aggregation pipeline here : mongoplayground
Ref : .updateOne()
Note : If in any case .updateOne() throws in an error due to in-compatible client or shell, try this query with .update(). This execution of aggregation pipeline in updates helps to save multiple DB calls & can be much useful on arrays with less no.of elements.

How to decode json array to find the last value of a variable using Perl?

I have a Json array of objects that I am trying to decode in perl. The json array looks like this :
[
{
"name": "a123",
"enroll": "12a123",
"cs": {
"year1": {
"status": {
"oldvalue": "pending",
"new value": "complete"
}
}
}
},
{
"name": "b123",
"enroll": "12b123",
"ecm": {
"year1": {
"flag": {
"oldvalue": "null",
"new value": "ok"
}
}
}
},
{
"name": "c123",
"enroll": "12c123",
"cs": {
"year1": {
"status": {
"oldvalue": "complete",
"new value": "run new"
}
}
}
}
]
I want to find the value of the {"status"}->{"new value"} from the last occurrence in the Json file.The output here should be "run new". FYI : not all fields are present in every object. Any help on how to parse this array will be highly appreciated.
I'd use a module for this - CPAN has a module called JSON:Parse which looks to do what you want:
use JSON::Parse 'parse_json';
my $json = loadJsonString(); # Load the JSON string from somewhere
my $courses = parse_json($json);
my $lastCourse = $courses->[-1];
my $newValue = $lastCourse->{cs}{year1}{status}{"new value"};

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

angularJS scope orderBy does not sort children, just the parent

When I used
$scope.data = $filter('orderBy')(data,'title');
the parent is sorted, the children are not.
What if my array has children? how can I order the parent and the children?
My array:
data = [
{
"id": 1,
"title": "abc",
"items": [
{
"id": 3,
"title": "abc2",
"items": []
},
{
"id": 4,
"title": "abc1",
"items": []
}
]
},
{
"id": 2,
"title": "cde",
"items": [
{
"id": 5,
"title": "cde2",
"items": []
},
{
"id": 6,
"title": "cde1",
"items": []
}
]
}
]
Thanks in advance.
It shouldn't sort anything within the child's objects.
For sorting within child object sort your 'items' recursively, for each child, with $filter('orderBy') or similar with code bellow use your own custom comparing function.
var orderByFieldName = 'title',
childPropertyForSorting = 'items',
s = function (a, b) {
//Revise comparing function depends on direction of sorting and your wishes
if (a[orderByFieldName] > b[orderByFieldName])
return 1;
if (a[orderByFieldName] < b[orderByFieldName])
return -1;
return 0;
},
f = function (o) {
if (o.hasOwnProperty(childPropertyForSorting) && o[childPropertyForSorting] instanceof Array) {
o[childPropertyForSorting].sort(s);
o[childPropertyForSorting].forEach(f);
}
};
if (originalData instanceof Array) {
originalData.sort(s);
originalData.forEach(f);
}
I would suggest if you are only trying to orderBy in the view to use
data-ng-repeat="item in data | orderBy: 'colum you want'"
Read more about it here
Reason is the children is in another level and treated just as another key value pair inside that object, you can use the same filter you used inside a for loop that will loop each data array item and sort the children like this :
//filter the parent level by title
$scope.data = $filter('orderBy')(data,'title');
//copy the sorted array in temp variable
var temp = angular.copy($scope.data);
//sort the children by title while aggregating each array item and then storing the output in $scope.
for(var i=0;i<data.length;i++){
$scope.data[i].items = $filter('orderBy')(temp[i].items,'title');
}

Resources