JavaScript sort a dictionary array - javascript

I have a question about sorting a dictionary object is JS es6. I am trying to filter the array but still keep the structure of an array in each month's object. Here is a mock of the data:
"soldListings": {
"Jan - 2020": [
{
"id": 159,
"user_id": 1,
"type_id": 1,
},
{
"id": 173,
"user_id": 1,
"type_id": 1,
},
{
"id": 563,
"user_id": 1,
"type_id": 2,
}
],
"Dec - 2019": [
{
"id": 183,
"user_id": 1,
"type_id": 1,
}
],
"Oct - 2019": [
{
"id": 176,
"user_id": 1,
"type_id": 1,
}
]
}
If it were a flat array of objects i would do something like:
typeFilter = data.filter((listing) => {
if(listing.type_id){
return listing.type_id == this.state.soldListTypeFilter ;
}
});
UPDATE
I need the output to be in the same format as the input. For example if i were to filter the object by type_id = 2 it would return this:
"soldListings": {
"Jan - 2020": [
{
"id": 563,
"user_id": 1,
"type_id": 2,
}
],
"Dec - 2019": [
],
"Oct - 2019": [
]
}

Use keySort function for this problem, for un-integer keys
Read https://stackoverflow.com/a/23202095/7146552
keySort( object, sortfn? )
function keySort(obj, sort) {
var keys = Object.keys(obj);
keys = keys.sort(sort);
var sortedObject = {};
for (var i = 0; i < keys.length; i++) {
sortedObject[keys[i]] = obj[keys[i]]
}
return sortedObject;
}
// Using
var obj = {
"z:": "Zvalue",
"a": "AValue"
};
console.log(obj);
obj = keySort(obj);
// or
obj = keySort(obj, (a, b) => {
return a > b ? 1 : -1
});
console.log(obj)
On your Question Test
function keySort(obj, sort) {
var keys = Object.keys(obj);
keys = keys.sort(sort);
var sortedObject = {};
for (var i = 0; i < keys.length; i++) {
sortedObject[keys[i]] = obj[keys[i]]
}
return sortedObject;
}
data = {
"Jan - 2020": [{
"id": 159,
"user_id": 1,
"type_id": 1,
},
{
"id": 173,
"user_id": 1,
"type_id": 1,
},
{
"id": 563,
"user_id": 1,
"type_id": 2,
}
],
"Dec - 2019": [{
"id": 183,
"user_id": 1,
"type_id": 1,
}],
"Oct - 2019": [{
"id": 176,
"user_id": 1,
"type_id": 1,
}]
}
data = keySort(data,function(a,b){
adate = new Date(a);
bdate = new Date(b);
return adate>bdate ? 1 : -1;
})
console.log(data);

Related

Can't loop array after grouping with .reduce

I've got the following meetings object :
[
{
"id": 19,
"duration": 1.75,
"Employee": {
"name": "Jeanne",
}
},
{
"id": 20,
"duration": 1.00,
"Employee": {
"name": "Louis",
}
},
{
"id": 21,
"duration": 1.00,
"Employee": {
"name": "Jeanne",
}
}
]
I want to group it by Employee.name. Using reduce() here is what I come up with :
meetings.reduce(function (r, a) {
r[a.Employee.name] = r[a.Employee.name] || [];
r[a.Employee.name].push(a);
return r;
}
The resulting object is the following :
{
"Jeanne": [
{
"id": 19,
"duration": 1.75,
"Employee": {
"name": "Jeanne"
}
},
{
"id": 21,
"duration": 1.00,
"Employee": {
"name": "Jeanne"
}
}
],
"Louis": [
{
"id": 20,
"duration": 1.00,
"Employee": {
"name": "Louis"
}
}
]
}
If I try to map() or forEach() i cannot get the value of the element :
Array.from(thisMeeting).forEach(element => console.log(element));
return `undefined`;
Array.from-ming an Object will result in an empty array.
You'll have to iterate over the objects keys with Object.entries(thisMeeting).forEach… and grab the values inside that.

How to get immediate parent Id of the child id in array of nested json Object?

I need to get the parent id of the specific child.
Here is my sample JSON, If I give entity id 32 it should return 6 as parent Id and if I give 30 it should return 5 as parent id.
const arr = [{
"id": 0,
"name": "My Entity",
"children": [
{
"id": 1,
"name": "MARKET",
"children": [
{
"id": 2,
"name": "Sales",
"children": [
{
"id": 3,
"name": "District 1",
"children": [
{
"id": 5,
"name": "Area 1",
"children": [
{
"entityId": 30,
"id": 26,
"name": "Mumbai"
},
{
"entityId": 31,
"id": 26,
"name": "Hyderabad"
}
],
"num": 0,
},
{
"id": 6,
"name": "Area 2",
"children": [
{
"entityId": 32,
"id": 32,
"name": "Karnataka"
},
{
"entityId": 33,
"id": 33,
"name": "Andhra Pradesh"
}
],
"num": 0,
},
]
},
]
},
]
},
]
}]
Here is the code I have tried
const findParent = (arr, entityId) => {
for (let i = 0; i < arr.length; i++) {
if (arr[i].entityId === entityId) {
return [];
} else if (arr[i].children && arr[i].children.length) {
const t = findParents(arr[i].children, entityId);
if (t !== false) {
t.push(arr[i].id);
return t;
}
}
}
return false;
};
findParents(arr, 30);
But it is returning like below
[
5,
3,
2,
1,
0
]
But I want the output to be
[
5
]
Kindly help me on this, thanks
Replace this:
t.push(arr[i].id);
with:
if (t.length == 0) t.push(arr[i].id);
I would suggest easier solution
const findParent = (arr, entityId) => {
const children = arr.flatMap(parent =>
(item.children || []).map(child => ({ parent, child, entityId: child.entityId }))
)
const res = children.find(item => item.entityId === entityId)
return res.entityId || findChildren(res.map(v => v.child), entityId)
}

Object Manipulation javascript

i have a big problem to manipulate a js object. I have this object :
"daily_operator_trend": {
"2018-08-01": {},
"2018-08-02": {},
"2018-07-16": {
"1": 1,
"2": 4,
"3": 3
},
"2018-07-18": {
"1": 1,
"3": 7
}
},
"operatorStats": [
{
"min_response_time": 5,
"max_deepness": 3,
"max_response_time": 5,
"min_deepness": 3,
"details": {
"phoneNumber": "001122333",
"allBots": true,
"surname": "Sky",
"nickname": "jesky",
"name": "Je",
"type": "owner",
"operatorId": 1,
"userId": "834f6de213c7d79bd64031371773b154",
"email": "jesky#hotmail.it",
"maxConversation": -1,
"botIdList": [
"1ec0e59069561da21727e3a56d05ef2d",
"0ddfc38f54f51f7b40e1057436b34a6f",
"37c43963d3e716bc4e41e1e6a32ed7f1"
]
},
"avg_deepness": 3,
"avg_response_time": 5
}]
Where in daily_operator_trend we have a key like a datae and a value is an object, in this object the key is the operator id and value is the num of conversation. I need to manipulate and transform it in a new array of object like this :
series: [ {name:'jesky', data:[0,0,1,1]}]
I'm trying with this code:
let columnDataConv = data.operatorStats.reduce(function(map, obj){
let newObj = [];
let cData = Object.keys(data.daily_operator_trend).reduce(function(m, o){
m['name'] = '';
m['data'] = [];
for (let [key, value] of Object.entries(data.daily_operator_trend[o])){
if (key == obj.details.operatorId){
if ( obj.details.nickname in m){
m['data'].push(value);
}else {
m['name']= obj.details.nickname;
m['data'].push(value);
}
}else {
m['data'].push(0);
}
newObj.push(m);
}
return newObj;
}, {})
map={...cData};
return map;
}, {});
Can you help me ?
const data = {
"daily_operator_trend": {
"2018-08-01": {
"1": 1,
"2": 4,
"3": 3
},
"2018-08-02": {
"1": 10,
"2":15,
"3":25
},
"2018-07-16": {
},
},
"operatorStats": [
{
"min_response_time": 5,
"max_deepness": 3,
"max_response_time": 5,
"min_deepness": 3,
"details": {
"phoneNumber": "001122333",
"allBots": true,
"surname": "Sky",
"nickname": "jesky",
"name": "Je",
"type": "owner",
"operatorId": 1,
"userId": "834f6de213c7d79bd64031371773b154",
"email": "jesky#hotmail.it",
"maxConversation": -1,
"botIdList": [
"1ec0e59069561da21727e3a56d05ef2d",
"0ddfc38f54f51f7b40e1057436b34a6f",
"37c43963d3e716bc4e41e1e6a32ed7f1"
]
},
"avg_deepness": 3,
"avg_response_time": 5
},
{
"min_response_time": 4,
"max_deepness": 2,
"max_response_time": 1,
"min_deepness": 2,
"details": {
"phoneNumber": "001122333",
"allBots": true,
"surname": "SkyWine",
"nickname": "john",
"name": "Jeremy",
"type": "owner",
"operatorId": 2,
"userId": "834f6de213c7d79bd64031371773b155",
"email": "john#hotmail.it",
"maxConversation": -1,
"botIdList": [
"1ec0e59069561da21727e3a56d05ef2d",
"0ddfc38f54f51f7b40e1057436b34a6g",
"37c43963d3e716bc4e41e1e6a32ed7f1"
]
},
"avg_deepness": 3,
"avg_response_time": 5
},
{
"min_response_time": 4,
"max_deepness": 2,
"max_response_time": 1,
"min_deepness": 5,
"details": {
"phoneNumber": "001122333",
"allBots": true,
"surname": "SkyWine",
"nickname": "Frank",
"name": "Jeremy",
"type": "owner",
"operatorId": 3,
"userId": "834f6de213c7d79bd64031371773b156",
"email": "frank#hotmail.it",
"maxConversation": -1,
"botIdList": [
"1ec0e59069561da21727e3a56d05ef2d",
"0ddfc38f54f51f7b40e1057436b34a6f",
"37c43963d3e716bc4e41e1e6a32ed7f2"
]
},
"avg_deepness": 3,
"avg_esponse_time": 5
}
]
};
function mergeNames (arr) {
return _.chain(arr).groupBy('name').mapValues(function (v) {
return _.chain(v).pluck('value').flattenDeep();
}).value();
}
let newObj = [];
let columnDataConv = data.operatorStats.reduce(function(map, obj){
for (let [k,v] of Object.entries(data.daily_operator_trend)){
for (let [key, value] of Object.entries(v)){
let m = {};
let dati = [];
if (key == obj.details.operatorId){
if(newObj.length > 0){
for(let i = 0;i< newObj.length; ++i){
if(newObj[i].name === obj.details.nickname){
dati=[];
dati.push(value);
newObj[i].data.push(...dati);
break;
}else{
dati=[];
m = {};
m['name']= obj.details.nickname;
dati.push(value);
m['data']=dati;
newObj.push(m);
break;
}
};
}else{
dati=[];
m = {};
m['name']= obj.details.nickname;
dati.push(value);
m['data']=dati;
newObj.push(m);
break;
}
}
}
}
map={...newObj};
return map;
}, []);
console.log(columnDataConv);
Now i have the array of objects but only the first entry of my array is correct. Why the other element aren't merged?

Trying to merge two arrays

Below is my json stored in :
$scope.regions = [];
{
"id": 100,
"regions": [
{
"id": 10,
"name": "Abc",
"rank": 0,
},
{
"id": 20,
"name": "Pqr",
"rank": 1,
},
{
"id": 30,
"name": "Lmn",
"rank": 2,
},
{
"id": 40,
"name": "xyz",
"rank": 3,
},
{
"id": 50,
"name": "GGG",
"rank": 4,
},
{
"id": 60,
"name": "YYY",
"rank": 5,
}
]
}
This is my another json stored in :
$scope.regionList = [];
var highestOrder = 3;
"regions": [
{
"id": 40,
"name": "xyz",
"rank": 0,
},
{
"id": 50,
"name": "GGG",
"rank": 1,
},
{
"id": 60,
"name": "YYY",
"rank": 2,
}
Now I want to merge $scope.regionList in to $scope.regions but for those records which are matching in both $scope.regionList and $scope.regions I would like to replace records of $scope.regions with $scope.regionList (only common records from both list).
And first non matching records from $scope.regionList will have order start using highestOrder and will keep incrementing for each non-matching records so final output will be like below :
Expected output :
"regions": [
{
"id": 10,
"name": "Abc",
"rank": 3,
},
{
"id": 20,
"name": "Pqr",
"rank": 4,
},
{
"id": 30,
"name": "Lmn",
"rank": 5,
},
{
"id": 40,
"name": "xyz",
"rank": 0,
},
{
"id": 50,
"name": "GGG",
"rank": 1,
},
{
"id": 60,
"name": "YYY",
"rank": 2,
}
As Abc is is the first non matching record so it will have order 3 and rest other will have order no from 3 i.e 4,5 6, etc.
My code:
var highestOrder = 3;
var found = false;
for (var i = 0; i < $scope.regions.length; i++) {
if ($scope.regions[i].id == 100) {
found = true;
for (var j = 0; j < $scope.regionList.length; j++) {
for (var k = 0; k < $scope.regions[i].regions.length; k++) {
if ($scope.regions[i].regions[k].id == $scope.regionList[j].id) {
$scope.regions[i].regions[k].rank = $scope.regionList[j].rank;
}
else {
$scope.regions[i].regions[k].rank = highestOrder;
highestOrder = highestOrder + 1;
}
}
}
}
if (found)
break;
}
var regions = {
"id": 100,
"regions": [{
"id": 10,
"name": "Abc",
"rank": 0,
},
{
"id": 20,
"name": "Pqr",
"rank": 1,
},
{
"id": 30,
"name": "Lmn",
"rank": 2,
},
{
"id": 40,
"name": "xyz",
"rank": 3,
},
{
"id": 50,
"name": "GGG",
"rank": 4,
},
{
"id": 60,
"name": "YYY",
"rank": 5,
}
]
}
var highestOrder = 3;
var found = false;
var regionList = [{
"id": 40,
"name": "xyz",
"rank": 0,
},
{
"id": 50,
"name": "GGG",
"rank": 1,
},
{
"id": 60,
"name": "YYY",
"rank": 2
}
]
for (var i = 0; i < regions.length; i++) {
if (regions[i].id == 100) {
found = true;
for (var j = 0; j < regionList.length; j++) {
for (var k = 0; k < regions[i].regions.length; k++) {
if (regions[i].regions[k].id == regionList[j].id) {
regions[i].regions[k].rank = regionList[j].rank;
} else {
regions[i].regions[k].rank = highestOrder;
highestOrder = highestOrder + 1;
}
}
}
}
if (found)
break;
}
console.log(regions)
You could use a hash table and build it with the elements of the array for updating.
Then iterate regions and update rank with either the hash's rank or with highestOrder. Increment highestOrder after assigning.
var $scope = { regions: [{ id: 100, regions: [{ id: 10, name: "Abc", rank: 0, }, { id: 20, name: "Pqr", rank: 1, }, { id: 30, name: "Lmn", rank: 2, }, { id: 40, name: "xyz", rank: 3, }, { id: 50, name: "GGG", rank: 4, }, { id: 60, name: "YYY", rank: 5, }] }] },
regionsUpdate = [{ id: 40, name: "xyz", rank: 0, }, { id: 50, name: "GGG", rank: 1, }, { id: 60, name: "YYY", rank: 2, }],
regionsId = 100,
highestOrder = 3,
hash = Object.create(null);
regionsUpdate.forEach(function (a) {
hash[a.id] = a;
});
$scope.regions.some(function (a) {
if (a.id === regionsId) {
a.regions.forEach(function (b) {
b.rank = hash[b.id] ? hash[b.id].rank : highestOrder++;
});
return true;
}
});
console.log($scope);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Getting/Filtering Object based on value [duplicate]

This question already has answers here:
How to filter object array based on attributes?
(21 answers)
Closed 6 years ago.
Can I filter or extract the values of an object, based on a value?
For example [10, 19] would return Bill and Sam.
[ { "id": 10, "nice_name": "Bill" },
{ "id": 12, "nice_name": "Dan"},
{ "id": 18, "nice_name": "Tony" },
{ "id": 19, "nice_name": "Sam" },
]
Thanks/
You can chain filter then map functions :
const mySearch = [10, 19]
const result = myArray.filter(elem => mySearch.indexOf(elem.id) > -1) // filter by id
.map(elem => elem.nice_name) // return the nice_name only for each entry
// result is now ['Bill', 'Sam']
You can use Array.prototype.filter() function:
const data = [ { "id": 10, "nice_name": "Bill" },
{ "id": 12, "nice_name": "Dan"},
{ "id": 18, "nice_name": "Tony" },
{ "id": 19, "nice_name": "Sam" },
]
const result = data.filter(o => ~[10, 19].indexOf(o.id))
// ~[10, 19].indexOf(o.id) is equivalent to [10, 19].indexOf(o.id) > -1
Using only javascript you can do something like this.
var size = a.length; //a -> your array
var inputSize = input.length; // -> the search array
var thePeople = []; //where you will store the names that match
for(var i = 0; i < size; i++) { //cycle your array
for(var j = 0; j < inputSize; j++) { //cycle the search array
if(a[i].id === input[j]) { //check if there is a match on id
thePeople.push(a[i].nice_name); //save the name into a new array
}
}
}
here is a fiddle https://jsfiddle.net/xo5vxwo0/
indexOf to find an element in array .
arr=[ { "id": 10, "nice_name": "Bill" },
{ "id": 12, "nice_name": "Dan"},
{ "id": 18, "nice_name": "Tony" },
{ "id": 19, "nice_name": "Sam" },
]
var fill=[10,19];
var ans=[];
arr.map(function(a){
if(fill.indexOf(a["id"])>-1)
ans.push(a["nice_name"]);
})
console.log(ans);
*{
background-color:pink;
}
var data = [ { "id": 10, "nice_name": "Bill" },
{ "id": 12, "nice_name": "Dan"},
{ "id": 18, "nice_name": "Tony" },
{ "id": 19, "nice_name": "Sam" },
]
var idWant = [10,19];
var content = '';
for(var keysWant in idWant){
var number = idWant[keysWant];
for(var keysData in data){
if(number == data[keysData]['id']){
content += data[keysData]['nice_name'] + ' ';
}
}
}
console.log(content);
One might use a single reduce instead of filter.map chain.
var arr = [ { "id": 10, "nice_name": "Bill" },
{ "id": 12, "nice_name": "Dan"},
{ "id": 18, "nice_name": "Tony" },
{ "id": 19, "nice_name": "Sam" },
],
src = [10,19],
result = arr.reduce((r,o) => src.includes(o.id ) ? r.concat(o.nice_name) : r,[]);
console.log(result);

Categories

Resources