I have a object.
var dl_items;
After a loop for inputing data:
dl_items[code] = itemObject;
I have a array:
dl_items : {
"code_A" : { "index" : 1, "status" : 2, "name" : A_data},
"code_B" : { "index" : 2, "status" : 0, "name" : B_data},
"code_C" : { "index" : 3, "status" : 1, "name" : C_data},
"code_D" : { "index" : 4, "status" : 2, "name" : D_data},
"code_E" : { "index" : 5, "status" : 4, "name" : E_data}
}
Now I want to remove "dl_items[code_D]" and insert it into after "code_A" (index 2) for result like :
dl_items : {
"code_A" : { "index" : 1, "status" : 2, "name" : A_data},
"code_D" : { "index" : 4, "status" : 2, "name" : D_data},
"code_B" : { "index" : 2, "status" : 0, "name" : B_data},
"code_C" : { "index" : 3, "status" : 1, "name" : C_data},
"code_E" : { "index" : 5, "status" : 4, "name" : E_data}
}
I try to use "delete" after using a loop to find index of code_D:
delete dl_items[code_D];
and it successful removed but how can i insert code_D into his new index ?
Edit : Thanks all everyone to help me understand more about array.
Since object doesn't have an order, you need to convert your current implementation into array:
var dl_items = [];
When you need to add an item to the array:
dl_items.push({ code: code, item: itemObject });
Now, the similar data as array from your question is:
dl_items: [
{ code :"code_A", item: { index: 1, status: 2, name: "A_data" } },
{ code :"code_B", item: { index: 2, status: 0, name: "B_data" } },
{ code :"code_C", item: { index: 3, status: 1, name: "C_data" } },
{ code :"code_D", item: { index: 4, status: 2, name: "D_data" } },
{ code :"code_E", item: { index: 5, status: 3, name: "E_data" } },
]
In order to move the entry with code_D after the entry with code_A, use the following:
var codeDEntry = dl_items[3];
dl_items = dl_items
.filter(function(entry) {
return entry !== codeDEntry;
})
.splice(1, 0, codeDEntry);
Hope this helps!
You can make a temp var like this :
tempItem = dl_items.code_D;
dl_items.code_D = dl_items.code_B;
dl_items.code_B = tempItem;
What you have here is an object, not an array. Therefore, there is no concept of an index here.
You can map your object keys into an array as follows:
let array = Object.keys(dl_items);
You can then reorder their positions.
Related
So I have an array of statuses and I want to get distinct values based on an element property ProductOrderStatusTypeID. I have one implementation but I want the cleanest way of doing that.
My list:
[{
StatusID : 1,
Name : "Open",
ProductOrderStatusType : 'Initial'
ProductOrderStatusTypeID : 1
},{
StatusID : 3,
Name : "Closed",
ProductOrderStatusType : 'Final'
ProductOrderStatusTypeID : 2
},
{
StatusID : 3,
Name : "Pending",
ProductOrderStatusType : 'Initial'
ProductOrderStatusTypeID : 1
}]
Expected output:
[{
ProductOrderStatusType : 'Initial',
ProductOrderStatusTypeID : 1
},{
ProductOrderStatusType : 'Final',
ProductOrderStatusTypeID : 2
}]
My code:
function getDistinctProductOrderStatusType(statuses) {
return statuses.reduce(function (result, status) {
var existingStatus = result.filter(function (res) {
return res.ProductOrderStatusTypeID === status.ProductOrderStatusTypeID;
})[0];
if (!existingStatus) {
result.push({
ProductOrderStatusTypeID: status.ProductOrderStatusTypeID,
ProductOrderStatusType: status.ProductOrderStatusType
});
}
return result;
}, []);
}
const stat = [{
StatusID: 1,
Name: "Open",
type: 'Initial', // !!! I renamed properties for simplicity sake
typeID: 1
}, {
StatusID: 3,
Name: "Closed",
type: 'Final',
typeID: 2
}, {
StatusID: 3,
Name: "Pending",
type: 'Initial',
typeID: 1
}
];
const distinctStat = arr => arr.reduce((a, {type, typeID}) =>
a.some(ob => ob.typeID === typeID) ? a : a.concat({type, typeID})
, []);
console.log( distinctStat(stat) );
In case you find it more easier to name the properties you're not interested in collecting (like i.y.e: StatusID and Name) than you could go for the rest element:
const distinctStat = arr => arr.reduce((a, {StatusID, Name, ...r}) =>
a.some(ob => ob.typeID === r.typeID) ? a : a.concat(r)
, []);
(same output as above)
Info:
Although we could, in the above code Array.prototype.some()
is used instead of Array.prototype.find()
because we don't need to return the entire object but just a boolean (as quickly as possible).
i have an object like this in my console:
ObjectName1 : Array(3)
0 : { id : 1, name : 'foo' },
1 : { id : 2, name : 'foo-2' },
2 : { id : 3, name : 'foo-3' },
ObjectName2 : Array(3)
0 : { id : 1, foo : 'bar' },
1 : { id : 2, foo-2 : 'bar-2' },
2 : { id : 3, foo-3 : 'bar-3' },
and as usually if we want to get the name, just write : ObjectName1[key].name right ?
now if i want to get the key from ObjectName2 (foo, foo-2, foo-3) how to get the key from ObjectName2 using the value from ObjectName1 ?
i have written like this :
// just say there is an each above this comment
var name = ObjectName1[key].name;
var bar = ObjectName2[key]+"."+name;
// end each
but it just showed
[Object object].foo
[Object object].foo-2
[Object object].foo-3
the output should be like this :
bar
bar-2
bar-3
it is possible doing like i want to do ? help me please if it is possible
any help will be very appreciated.
*note : i'm not sure what is the case name in my problem, so forgive me if the title went wrong
thanks
Try this one. Loop through each object in ObjectName1 object and get the name in appropriate index, this name will be the key for the ObjectName2 object. Then use that key to print the appropriate value from ObjectName2
var ObjectName1 = [{'id' : 1, 'name' : 'foo'}, {'id' : 2, 'name' : 'foo-2'}, {'id' : 3, 'name' : 'foo-3'}];
var ObjectName2 = [{'id' : 1, 'foo' : 'bar'}, {'id' : 2, 'foo-2' : 'bar-2'}, {'id' : 3, 'foo-3' : 'bar-3'}];
for(var i = 0; i < ObjectName2.length; i++){
console.log(ObjectName2[i][ObjectName1[i]['name']]);
}
Something like this?
var name = ObjectName1[key].name;
ObjectName2.forEach(function(a) {
if (a.keys().includes(name)) {
var bar = a[name];
// then do what you want with bar
}
}
As commented, your key is an object. Hence, it is showing [Object object].foo-3.
You will have to use 2 loops and check if the key is inside current object. If yes, print it, else continue.
var ObjectName1 =[
{ id : 1, name : 'foo' },
{ id : 2, name : 'foo-2' },
{ id : 3, name : 'foo-3' },
]
var ObjectName2 = [
{ id : 1, foo : 'bar' },
{ id : 2, 'foo-2' : 'bar-2' },
{ id : 3, 'foo-3' : 'bar-3' },
];
ObjectName1.forEach(function(obj){
ObjectName2.forEach(function(obj2){
var key = obj.name;
if(key in obj2){
console.log(obj2[key])
}
})
})
now if i want to get the key from ObjectName2 (foo, foo-2, foo-3) how to get the key from ObjectName2 using the value from ObjectName1 ?
If you know those are parallel arrays (where [0] in one array is intentionally a match for [0] in the other array), you can simply loop through:
ObjectName1.forEach(function(entry1, index) {
var value = ObjectName2[index][entry1.name];
console.log(entry1.name + " = " + value);
});
Example:
var ObjectName1 = [
{ id : 1, name : 'foo' },
{ id : 2, name : 'foo-2' },
{ id : 3, name : 'foo-3' }
];
var ObjectName2 = [
{ id : 1, "foo" : 'bar' },
{ id : 2, "foo-2" : 'bar-2' },
{ id : 3, "foo-3" : 'bar-3' }
];
ObjectName1.forEach(function(entry1, index) {
var value = ObjectName2[index][entry1.name];
console.log(entry1.name + " = " + value);
});
That assumes you know they're parallel arrays.
If not, you have to search for it. Array.prototype.findIndex will return the index of the first element where a callback returns true:
ObjectName1.forEach(function(entry1) {
console.log("entry1.name = " + entry1.name);
var index = ObjectName2.findIndex(function(entry2) {
// See if entry2 contains a key with that value
return entry1.name in entry2;
});
console.log(index == -1 ? "Not found" : ("Found at index #" + index + ", value = " + ObjectName2[index][entry1.name]));
});
Example:
var ObjectName1 = [
{ id : 1, name : 'foo' },
{ id : 2, name : 'foo-2' },
{ id : 3, name : 'foo-3' }
];
var ObjectName2 = [
{ id : 1, "foo" : 'bar' },
{ id : 2, "foo-2" : 'bar-2' },
{ id : 3, "foo-3" : 'bar-3' }
];
ObjectName1.forEach(function(entry1) {
console.log("entry1.name = " + entry1.name);
var index = ObjectName2.findIndex(function(entry2) {
// See if entry2 contains a key with that value
return entry1.name in entry2;
});
console.log(index == -1 ? "Not found" : ("Found at index #" + index + ", value = " + ObjectName2[index][entry1.name]));
});
If you don't really need the key (e.g., index) of the matching object in ObjectName2, just the object, use find instead:
ObjectName1.forEach(function(entry1) {
console.log("entry1.name = " + entry1.name);
var entry = ObjectName2.find(function(entry2) {
// See if entry2 contains a key with that value
return entry1.name in entry2;
});
console.log(!entry ? "Not found" : ("Found, value is " + entry[entry1.name]));
});
Example:
var ObjectName1 = [
{ id : 1, name : 'foo' },
{ id : 2, name : 'foo-2' },
{ id : 3, name : 'foo-3' }
];
var ObjectName2 = [
{ id : 1, "foo" : 'bar' },
{ id : 2, "foo-2" : 'bar-2' },
{ id : 3, "foo-3" : 'bar-3' }
];
ObjectName1.forEach(function(entry1) {
console.log("entry1.name = " + entry1.name);
var entry = ObjectName2.find(function(entry2) {
// See if entry2 contains a key with that value
return entry1.name in entry2;
});
console.log(!entry ? "Not found" : ("Found, value is " + entry[entry1.name]));
});
I do not know how to implement the reduce function.
I have output from my map a document as ...
for example two documents
key "_id":"AD"
"values"
{
"numtweets" : 1,
"hastags" : {
"OPINIÓ" : 1,
"debat" : 1,
"inexistent" : 1,
"tampoc" : 1,
"promet" : 1,
"gaire" : 1,
"diàleg" : 1
}
}
and other
{
"numtweets" : 1,
"hastags" : {
"other" : 1,
"debat" : 1,
"inexistent" : 1,
"another" : 1,
}
}
I need a function that reduces all sum so that
"numtweets" : 2,
"dicwords" : {
"OPINIÓ" : 1,
"debat" : 2,
"inexistent" : 2,
"tampoc" : 1,
"promet" : 1,
"gaire" : 1,
"diàleg" : 1,
"other" : 1,
"another" : 1
},
"lisuser" : {
"user2" : 1
}
if my json values was only nuwtweets the reduce is
function(key, values) {
return Array.sum(values);
};
if mi json values only was hastags (without numtweets and lisuser) the reduce function was
var r = function(key, values) {
result = {}
values.forEach(function(val) {
for (hashtag in val) {
if (hashtag in result) {
result[hashtag] = result[hashtag] + val[hashtag]
} else {
result[hashtag] = val[hashtag]
}
}
});
return(result)
};
But I don't know how mix the 2 reduce function.
My level of mongodb and JavaScript is very low.
Thanks
Try this:
let data = values.reduce((finalObj, ele) => {
finalObj.numtweets += ele.numtweets
for (key in ele.hastags) {
if(ele.hastags.hasOwnProperty(key)) {
if(finalObj.hastags[key])
finalObj.hastags[key] += ele.hastags[key]
else
finalObj.hastags[key] = ele.hastags[key]
}
}
return finalObj
})
console.log(data)
Where values is array for objects which you want reduce to one object
I've been trying to use the MapReduce functionaltity in Mongo 2.6.11 to help in returning an array of objects as a value to a corresponding key.
For example, given the following input to a MapReduce job:
{ IncidentNumber : 123, StartLoc : 5, EndLoc : 10, },
{ IncidentNumber : 123, StartLoc : 10, EndLoc : 15, },
{ IncidentNumber : 123, SStartLoc : 10, EndLoc : 15, },
{ IncidentNumber : 321, StartLoc : 0, EndLoc : 5, },
{ IncidentNumber : 321, StartLoc : 10, EndLoc : 20, }
I would like to get output that looks like this:
{ IncidentNumber : 123, Locations : [{StartLoc : 5, EndLoc : 10},{StartLoc : 10, EndLoc : 15}, {StartLoc : 10, EndLoc : 15}],
{ IncidentNumber : 321, Locations : [{StartLoc : 0, EndLoc : 5},{StartLoc : 10, EndLoc : 20}]
My current map and reduce functions for this is as follows:
var mapFunction = function() {
emit(this.IncidentNumber, {StartLoc : this.StartLoc, EndLoc: this.EndLoc} )
}
var reduceFunction = function(key, values) {
var out = []
return out.push(values);
}
This is giving me results that look like:
{ "_id" : 50144, "value" : 1 }
{ "_id" : 68971, "value" : { "startLoc" : 10, "endLoc" : 5} }
{ "_id" : 108294, "value" : 1 }
{ "_id" : 165130, "value" : 1 }
{ "_id" : 194016, "value" : 1 }
{ "_id" : 210018, "value" : 1 }
{ "_id" : 210195, "value" : 1 }
{ "_id" : 212069, "value" : 1 }
I know my reduce function is not correct and I'm not sure if this is an odd use case as I'm not really doing any actual 'reduction'. But I'm not sure exactly what the problem is. Any help would be much appreciated.
Thanks.
After some more searching I found a way of a getting this to work based on this post MongoDB Map/Reduce Array aggregation question. For anyone who is trying to solve the same problem The map/reduce functions I've used are as follows:
var mapFunction = function() {
emit( {
incident: this.IncidentNumber,
} , {
data: [ { start : this.startLoc, end : this.endLoc} ]
} );
}
var reduceFunction = function(key,values) {
var out = [];
values.forEach(function(d){
Array.prototype.push.apply(out, d.data);
});
return { data: out };
}
I have a Schema
{
name: {type:String}
.....
child : {type: [childSchema], []}
}
and A child schema
{
x:{type:Number}
y:{type:Number},
options: {type:Array, default}
}
The problem is while I can update an individual children properties with a particular child id, I cannot update/replace the Options array (just an array of strings), I have
parent.findOneAndUpdate({
_id: id,
status: 'draft',
child: {
$elemMatch: {
_id: childId
}
}
}, {
$set: {
child.$.x : newX,
child.$.y : newy,
child.$.options : ['option1', 'option2']
}
}).lean().exec()
I have also tried
$set: {
'child.$.x' : newX,
'child.$.y' : newy,
'child.$.options' : { '$all' ['option1', 'option2']}
}
I think (but I am unsure) that maybe I cannot use any of the $ functions ($set, $all) at this level
When I google I seem to find more links about updating subdocument and can find anything on replacing an array in a subdocument, tried looking in the Mongodb & mongoose API but Unless I am overlooking something I can't find anything that would work in this case
can anyone point me in the right direction
Try an update like in the following example from the mongo shell:
> db.test.drop()
> db.test.insert({
"_id" : 0,
"children" : [
{ "_id" : 1, "x" : 1, "y" : 2, "options" : [1, 2, 3] },
{ "_id" : 2, "x" : 5, "y" : 8, "options" : [1, 6, 2] }
]
})
> db.test.update({ "_id" : 0, "children._id" : 1 },
{ "$set" : { "children.$.x" : 55, "children.$.y" : 22, "children.$.options" : [9, 8, 7] } }
)
> db.test.findOne()
{
"_id" : 0,
"children" : [
{ "_id" : 1, "x" : 55, "y" : 22, "options" : [9, 8, 7] },
{ "_id" : 2, "x" : 5, "y" : 8, "options" : [1, 6, 2] }
]
}