array inside another array - javascript

Problem Statement
I'm trying to create an array with another array inside this array, but it doesn't work for me.
This is what i wrote:
var arr = '{"project":['
+ '{"id":"01","name":"project1","activity":['
+ '{"num":"001","time":"7","desc":"desc","stam":['
+ ' "pre":"005","pre2":"002"]}'
+ '{"num":"002","time":"6","desc":"desc"}'
+ '{"num":"003","time":"5","desc":"desc"}'
+ '{"num":"004","time":"4","desc":"desc"}'
+ '{"num":"005","time":"3","desc":"desc"}]}]}';

Your JSON looks corrupted. You can use several online editors and validators to verify the JSON string. editor and validator just as an example of mony others. You also might have a look here.
, is missing between the array elements
the property stam looks more like an object than an array
It should look like this:
{"project":[
{"id":"01","name":"project1","activity":
[
{"num":"001","time":"7","desc":"desc","stam":{
"pre":"005",
"pre2":"002"
}
},
{"num":"002","time":"6","desc":"desc"},
{"num":"003","time":"5","desc":"desc"},
{"num":"004","time":"4","desc":"desc"},
{"num":"005","time":"3","desc":"desc"}
]
}
]
}

The json is not formatted correctly:
{
project : [{
id : "01",
name: "project1",
activity :[
{
num : "001",
time : "7",
desc : "desc",
stam : [{
pre : "005",
pre2: "002"
}]
},
{
num : "002",
time: "6",
desc: "desc"
},
{
num : "003",
time: "5",
desc:"desc"
},
{
num : "004",
time: "4",
desc: "desc"
},
{
num : "005",
time: "3",
desc: "desc"
}
]
}]
}

Related

how to format json in angular

I want to know how to format my json to have key and value using typescript with Angular framework,
with the current method if I use the keyvalue pipe in my html it will work but I want to format the json.
In my example below I have my Current json and the expected json so that you can see the result I expect and to be as clear as possible being a beginner in the business I wanted to be clear
Current.json
{
"url": "url test"
"flight": [
[
"1",
"apollo",
"ariane"
],
[
"2",
"Space X",
"Boca chica"
]
]
}
expected.json // this json is what I would like to have
{
"url": "url test"
"flight": [
[
id: "1",
name: "apollo",
rocket:"ariane"
],
[
id: "2",
name: "Space X",
rocket: "falcon 9"
]
]
}
ts.file
get() {
this.service.get().subscribe((data: Interface[])=> {
this.array = data
});
Your expected Json isn’t valid, if you want property names for those array values you need to make them an object.
{
"url": "url test"
"flight": [
{
id: "1",
name: "apollo",
rocket:"ariane"
},
{
id: "2",
name: "Space X",
rocket: "falcon 9"
}
]
}
To get this format from the example you gave you can do this:
get() {
this.service.get().subscribe((data: Interface[])=> {
data.flight = data.flight.map(f => ({id: f[0], name: f[1], rocket: f[2]}))
this.array = data
});
Please try this code snippet
get() {
this.service.get().subscribe((data: any)=> {
data.flight = data.flight.map(f => {
return {id: f[0], name: f[1], rocket: f[2]}
})
this.array = data
});

How to update a subdocument in array - mongoose [duplicate]

I have a document structured like this:
{
_id:"43434",
heroes : [
{ nickname : "test", items : ["", "", ""] },
{ nickname : "test2", items : ["", "", ""] },
]
}
Can I $set the second element of the items array of the embedded object in array heros with nickname "test" ?
Result:
{
_id:"43434",
heroes : [
{ nickname : "test", items : ["", "new_value", ""] }, // modified here
{ nickname : "test2", items : ["", "", ""] },
]
}
You need to make use of 2 concepts: mongodb's positional operator and simply using the numeric index for the entry you want to update.
The positional operator allows you to use a condition like this:
{"heroes.nickname": "test"}
and then reference the found array entry like so:
{"heroes.$ // <- the dollar represents the first matching array key index
As you want to update the 2nd array entry in "items", and array keys are 0 indexed - that's the key 1.
So:
> db.denis.insert({_id:"43434", heroes : [{ nickname : "test", items : ["", "", ""] }, { nickname : "test2", items : ["", "", ""] }]});
> db.denis.update(
{"heroes.nickname": "test"},
{$set: {
"heroes.$.items.1": "new_value"
}}
)
> db.denis.find()
{
"_id" : "43434",
"heroes" : [
{"nickname" : "test", "items" : ["", "new_value", "" ]},
{"nickname" : "test2", "items" : ["", "", "" ]}
]
}
Try update document in array using positional $,
The positional $ operator facilitates updates to arrays that contain embedded documents. Use the positional $ operator to access the fields in the embedded documents with the dot notation on the $ operator.
db.collection.update(
{ "heroes.nickname": "test" },
{ $set: { "heroes.$.items.1": "new_value" } },
{ multi: true }
);
Playground
This solution works well. Just want to add one point.
Here is the structure. I need to find OrderItemId is 'yyy' and update.
If the query field in condition is an array, like below "OrderItems.OrderItemId" is array. You can not use "OrderItems.OrderItemId[0]" as operation in the query. Instead, you need to use "OrderItems.OrderItemId" to compare. Otherwise, it can not match one.
{
_id: 'orderid',
OrderItems: [
{
OrderItemId: ['xxxx'],
... },
{
OrderItemId: ['yyyy'],
...},
]
}
result = await collection.updateOne(
{ _id: orderId, "OrderItems.OrderItemId": [orderItemId] },
{ $set: { "OrderItems.$.imgUrl": imgUrl[0], "OrderItems.$.category": category } },
{ upsert: false },
)
console.log(' (result.modifiedCount) ', result.modifiedCount)
console.log(' (result.matchedCount) ', result.matchedCount)
Try update with positional $ and $position,
db.collection.update(
{ heroes:{ $elemMatch:{ "nickname" : "test"} } },
{
$push: {
'heroes.$.items': {
$each: ["new_value" ],
$position: 1
}
}
}
)
go further! Use string template for paste your variable indexes in the way
yourModel.findOneAndUpdate(
{ _id: "43434" },
{
$set: {
[`heroes.${heroesIndex}.items.${itemIndex}`]: "new_value",
},
}
);
or
without template
yourModel.findOneAndUpdate(
{ _id: "43434" },
{
$set: {
'heroes.0.items.1': "new_value",
},
}
);

How to use javascript lodash uniqBy on a nested attribute

I have an object that is structured similar as follows (simplified version):
{
"time": 100,
"complete" : true,
"results" : {
"total": 10,
"score": 3,
"results": [
{
"id" : 123,
"name": "test123"
},
{
"id" : 123,
"name": "test4554"
}
]
}
}
How do I use lodash ._uniqBy to deduplicate the results, based on results.results.id being the unique key?
To clarify, I would like the deduplicated resultset to be returned within the original object structure, e.g.
{
"time": 100,
"complete" : true,
"results" : {
"total": 10,
"score": 3,
"results": [
{
"id" : 123,
"name": "test123"
}
]
}
}
thanks
You can achieve your goal by simply passing the right part of your object into _.uniqBy(array, [iteratee=_.identity]) function.
Next thing you want to do is to 'concat' lodash uniqBy result and your object. This is a little bit tricky. I suggest you to use ES6 Object.assign() method and spread operator.
Check out my solution. Hope this helps.
const myObj = {
"time": 100,
"complete" : true,
"results" : {
"total": 10,
"score": 3,
"results": [
{"id" : 123, "name": "test123"},
{"id" : 123, "name": "test4554"}
]
}
};
const uniq = _.uniqBy(myObj.results.results, 'id');
const resultWrapper = Object.assign({}, myObj.results, { results: [...uniq] });
const resultObj = Object.assign({}, myObj, { results: resultWrapper });
console.log( resultObj );
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.5/lodash.min.js"></script>
You can use something like this
const myObj = {
time: 100,
complete : true,
results : {
total: 10,
score: 3,
results: [
{id : 123, name: "test123"},
{id : 123, name: "test4554"}
]
}
};
_.set(myObj, 'results.results', _.uniqBy(_.get(myObj, 'results.results'), 'id'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>

Angular bind to filtered count

I have this array:
[
{
type: "hhh",
items: [
{
"name": "EGFR",
"type": "a",
"selected": true
}
]
},
{
type: "aaa",
items: [
{
"name": "mm",
"type": "b",
"selected": false
}
]
},
{
type: "ii",
items: [
{
"name": "pp",
"type": "bb",
"selected": true
}
]
}
]
I want to show a counter of the items with selected property "true".
I want it to be changed real time when change.
(Without watch and function)
Thnaks!
Here is the way:
var current_selected = {
get amount(){
var res = 0;
arr.forEach(function(item, i, arr) {
if (item.items[0].selected) res++;
})
return res;
}
}
Calling:
current_selected.amount
Fiddle
You can use JsonPath to get the count. Also using JsonPath has an added advantage of working on complex json structure. For the example you gave, you just need to include jsonpath js file and use the following in your script:
console.log(arr);
var filtered = jsonPath(arr, "$.[*].items[?(#.selected==true)]");
console.log(filtered);
console.log(filtered.length);
where arr is your json structure.
JsonPath can be got from :
https://code.google.com/archive/p/jsonpath/downloads
JsonPath help:
http://goessner.net/articles/JsonPath/
There might be updated version in other sources but that was the one I had worked on

Group Array into a more complex Array

I create an array of Objects from a database query and call the
array jobListRecords. There are multiple records in the array created that have the same "customerID" and "name".
I would like to create a new array that has one record for each customer with a new field , "jobArray", that contains another array of all of that customers services. (see sortCustomer array down below)
An example of the initial array:
jobListRecords = [
{
"customerID" : "1",
"name" : "Larry Bird",
"serviceID" : "101",
"serviceName" : "Dog Walking"
},
{
"customerID" : "2",
"name" : "Andrew Luck",
"serviceID" : "202",
"serviceName" : "Baby Sitting"
},
{
"customerID" : "2",
"name" : "Andrew Luck",
"serviceID" : "101",
"serviceName" : "Dog Walking"
}
]
Desired Result
sortCustomer Example:
sortCustomer = [
{
"customerID" : "1",
"name" : " Larry Bird",
"jobArray" : [
{
"serviceID" : "101",
"serviceName" : "Dog Walking"
}
]
},
{
"customerID" : "2",
"name" : "Andrew Luck",
"jobArray" : [
{
"serviceID" : "202",
"serviceName" : "Baby Sitting"
},
{
"serviceID" : "101",
"serviceName" : "Dog Walking"
}
]
}
Is their a simple or efficient way of solving this without having to iterate through all the data 3+ times. Thank You for your time, below is one of the several things I tried.
I tried solving this using one example I found but it grouped all the serviceIDs together which is not what I need.
Example that DID NOT work that I tried.
jobListGrouped = _
.chain(jobListRecords)
.groupBy('customerID')
.map(function(value, key) {
return {
CustomerID: key,
services: _.pluck(value, 'serviceID')
}
})
.value();
You're plucking only the serviceIDs into that array. Instead, you would need to do something like
.map(function(values, key) {
return {
customerID: key,
name: values[0].name.
services: _.map(values, _.partial(_.pick, _, 'serviceID', 'serviceName'))
}
})
or even more explicit
.map(function(values, key) {
return _.extend(_.omit(values[0], 'serviceID', 'serviceName'), {
services: _.map(values, _.partial(_.pick, _, 'serviceID', 'serviceName'))
}
})
(where that partial call is the same as function(value) { return _.pick(value, 'serviceID', 'serviceName'); })

Categories