Transform an array with attributes into a list - javascript

I am working with a graphics library and it is very bad to manipulate the data coming from the API. The problem is that the chart lib does not accept the data format that the api I am using returns.
API response
const data = [
{
"house01": {
"free": 6
},
"house02": {
"free": 2
},
"house03": {
"free": 1
},
}
]
Expected (UPDATED)
const data = [
{
"label": "house01"
"free": 6
},
{
"label": "house02"
"free": 2
},
{
"label": "house03"
"free": 1
},
]

Is this what you're looking for?
const data = [
{
house01: {
free: 6
},
house02: {
free: 2
},
house03: {
free: 1
}
}
];
const expectedData = Object.entries(data[0]).map(d => ({
label: d[0],
free: d[1].free
}));
console.log(expectedData)
const data2 = {
house01: { free: 6 },
house02: { free: 2 },
house03: { free: 1 }
};
const expectedData2 = Object.entries(data2).map(d => ({
label: d[0],
free: d[1].free
}));
console.log(expectedData2);

const data = [{
"house01": {
"free": 6
},
"house02": {
"free": 2
},
"house03": {
"free": 1
},
}]
final = [];
temp = {};
Object.entries(data[0]).forEach(student => {
temp.label = student[0];
Object.entries(student[1]).forEach(student1 => {
temp[student1[0]] = student1[1];
})
final.push(temp);
});
console.log(final);
Hope this works for you don't forget to Upvote my answer if this helps you

Related

Retrieving data from a complex inconsistent JSON

I'm trying to set variables from a JSON object that I retrieve with a POST query. But the results aren't returned in the same order every time, so it doesn't always work. I'm not sure how to correctly set my variables with the array positions not remaining constant:
var idle = Example1.results[0].data[1].stats.count;
var waiting = Example1.results[1].data[0].stats.count;
(i.e. This works on example 1, but not example 2)
Example1 = {"results":[{"group":{"queueId":"someID"},"data":[{"metric":"oOnQueueUsers","qualifier":"INTERACTING","stats":{"count":2}},{"metric":"oOnQueueUsers","qualifier":"IDLE","stats":{"count":5}}]},{"group":{"queueId":"someID","mediaType":"voice"},"data":[{"metric":"oWaiting","stats":{"count":0}}]}]}
Example2 = {"results":[{"group":{"queueId":"someID","mediaType":"voice"},"data":[{"metric":"oWaiting","stats":{"count":1}}]},{"group":{"queueId":"someID"},"data":[{"metric":"oOnQueueUsers","qualifier":"INTERACTING","stats":{"count":4}},{"metric":"oOnQueueUsers","qualifier":"IDLE","stats":{"count":6}}]}]}
You can use find() and some() to get the result you want.
const example1 = { results: [ { group: { queueId: "someID" }, data: [ { metric: "oOnQueueUsers", qualifier: "INTERACTING", stats: { count: 2 }, }, { metric: "oOnQueueUsers", qualifier: "IDLE", stats: { count: 5 } }, ], }, { group: { queueId: "someID", mediaType: "voice" }, data: [{ metric: "oWaiting", stats: { count: 0 } }], }, ], };
const example2 = { results: [ { group: { queueId: "someID", mediaType: "voice" }, data: [{ metric: "oWaiting", stats: { count: 1 } }], }, { group: { queueId: "someID" }, data: [ { metric: "oOnQueueUsers", qualifier: "INTERACTING", stats: { count: 4 }, }, { metric: "oOnQueueUsers", qualifier: "IDLE", stats: { count: 6 } }, ], }, ], };
const idle1 = example1.results
.find(a => a.data.some(d => d.qualifier === "IDLE"))
.data.find(b => b.qualifier === "IDLE").stats.count;
const waiting1 = example1.results
.find(a => a.data.some(d => d.metric === "oWaiting"))
.data.find(b => b.metric === "oWaiting").stats.count;
const idle2 = example2.results
.find(a => a.data.some(d => d.qualifier === "IDLE"))
.data.find(b => b.qualifier === "IDLE").stats.count;
const waiting2 = example2.results
.find(a => a.data.some(d => d.metric === "oWaiting"))
.data.find(b => b.metric === "oWaiting").stats.count;
console.log({ idle1 }, { waiting1 }, { idle2 }, { waiting2 });
If you cannot depend on the order being the same every time... or given your example data that each object doesn't even have the same properties... then you shouldn't search the resultant json for your data.
Rather then, you need to create your own data structure against which you will be able to search/index and then loop through your json, parsing each level within to decide how to map that particular element to your new data structure.
Here's an example of what you might could do...
var exampleResults1 = {
"results": [{
"group": {
"queueId": "someID"
},
"data": [{
"metric": "oOnQueueUsers",
"qualifier": "INTERACTING",
"stats": {
"count": 2
}
},
{
"metric": "oOnQueueUsers",
"qualifier": "IDLE",
"stats": {
"count": 5
}
}
]
},
{
"group": {
"queueId": "someID",
"mediaType": "voice"
},
"data": [{
"metric": "oWaiting",
"stats": {
"count": 0
}
}]
}
]
}
var newDataSource = {
parseResults: function(resultObj) {
resultObj.results.forEach(function(result) {
var queueID = result.group.queueId;
if (!newDataSource.hasOwnProperty(queueID)) {
newDataSource[queueID] = {
data: {}
};
}
var newDataSourceQueue = newDataSource[queueID];
result.data.forEach(function(dataObj) {
var metric = dataObj.metric;
if (!newDataSourceQueue.data.hasOwnProperty(metric)) {
newDataSourceQueue.data[metric] = {};
}
var queueMetric = newDataSourceQueue.data[metric];
var qualifier = "noQualifier";
if (dataObj.hasOwnProperty("qualifier")) {
qualifier = dataObj.qualifier;
}
queueMetric[qualifier] = {};
var metricQualifier = queueMetric[qualifier];
var statKeys = Object.keys(dataObj.stats);
statKeys.forEach(function(stat) {
if (!metricQualifier.hasOwnProperty(stat)) {
metricQualifier[stat] = dataObj.stats[stat];
}
});
});
});
}
};
newDataSource.parseResults(exampleResults1);
console.log(JSON.stringify(newDataSource));
console.log("IDLE Count = " + newDataSource["someID"]["data"]["oOnQueueUsers"]["IDLE"]["count"]);
Running this code, you should be able to see what the new data structure looks like after its been populated with values from your original json object. Notice how the keys of the objects are values from the original json.
My example code here doesn't take into account all data points in your example result sets... but should be enough to illustrate that you need to understand the data you are getting back and be able to come up with a consolidated data structure to encapsulate it using property keys that come from the actual returned results.

How to filter in two deep arrays

I'm looking to filter in two deep arrays, actually my JSON:
{
"0": {
"product":[{
"uuid":"uid",
"name":"Rice"
},
{
"uuid":"uid",
"name":"Pasta"
}]
},
"1": {
"product":[{
"uuid":"uid",
"name":"Milk"
}]
}
}
I would like to get something like that when I filter with the word "ric":
{
"0": {
"product":[{
"uuid":"uid",
"name":"Rice"
}]
}
}
But I got this result:
{
"0": {
"product":[{
"uuid":"uid",
"name":"Rice"
},
{
"uuid":"uid",
"name":"Pasta"
}]
}
}
My code:
dataSort.categories = the json and
event.target.value.toLowerCase() = the specific word
dataSort.categories.filter(s => s.products.find(p => p.name.toLowerCase().includes(event.target.value.toLowerCase())));
You can achieve this with a combination of reduce and filter
var input = {
"0": {
"product":[{
"uuid":"uid",
"name":"Rice"
},
{
"uuid":"uid",
"name":"Pasta"
}]
},
"1": {
"product":[{
"uuid":"uid",
"name":"Milk"
}]
}
}
var search = "ric"
var result = Object.entries(input).reduce( (acc, [key,val]) => {
found = val.product.filter(x => x.name.toLowerCase().includes(search.toLowerCase()))
if(found.length){
acc[key] = {...val, product: found}
}
return acc
},{})
console.log(result)
There is many approach to do this, one is to map your top level array to the subArrays filtered results then filter it after:
dataSort.categories
.map(s => s.products.filter(p => p.name.toLowerCase().includes(event.target.value.toLowerCase())))
.filter(s => !!s.products.length);
You may also prefer to get a "flat" array as result because it is easier to use after :
dataSort.categories
.reduce((acc, s) => [...acc, s.products.filter(p => p.name.toLowerCase().includes(event.target.value.toLowerCase()))], []);
Please find below the code to filter out values inside the product.name and only return the value which are matching the equality condition in product array.
const json = [
{
product: [
{
uuid: "uid",
name: "Rice",
},
{
uuid: "uid",
name: "Pasta",
},
],
},
{
product: [
{
uuid: "uid",
name: "Milk",
},
],
},
];
const inputValue = "rIc";
const filteredArray = [];
json.map((s) => {
const item = s.product.find((p) =>
p.name.toLowerCase().includes(inputValue.toLowerCase())
);
item && filteredArray.push({ product: item });
});
console.dir(filteredArray);
Your dataset is an Object, not an Array and the filter is an Array method. You can use reduce by looping on the object values by Object.values then filter your products array.
const data = {
'0': {
product: [
{
uuid: 'uid',
name: 'Rice',
},
{
uuid: 'uid',
name: 'Pasta',
},
],
},
'1': {
product: [
{
uuid: 'uid',
name: 'Milk',
},
],
},
};
const keyword = 'ric';
const dataset = Object.values(data);
const results = dataset.reduce((acc, item, index) => {
const search = keyword.toLowerCase();
const product = item.product.filter(product => product.name.toLowerCase().includes(search));
if (product.length) acc[index] = { ...item, product };
return acc;
}, {});
console.log(results);

how to find mismatch elements between two nested array in react

I have two arrays below.
array 1:
{
"0":{
"countries":{
"BDI":{
"count":1
},
"IRN":{
"count":1
}
},
"checkId":"16835659691517226105"
},
"1":{
"countries":{
"ZAF":{
"count":2
}
},
"checkId":"144165083478491226"
}
}
array2:
{
"0":{
"countries":{
"AIA":{
"count":2
}
},
"checkId":"144165083478491106"
},
"1":{
"countries":{
"BDI":{
"count":1
},
"IRN":{
"count":1
},
"ATA":{
"count":5
}
},
"checkId":"16835659691517226105"
}
}
I want to find the mismatch and common element between the two arrays. currently, I am executing two for loops to find the matching element between two array-based on checkids but I am not able to find the non-common elements from these two.
some code snippets
array1.forEach(each => {
array2.forEach(compareTask => {
var teastEach = Object.entries(compareTask.countries);
if (each.checkId === compareTask.checkId) {
firstCount = each.count
secondCount = compareTask.count
countDifference = secondCount - firstCount
......
I am able to get the common checkids but not getting the non-common checkids.
expected output:
{
"0":{
"countries":{
"ZAF":{
"count":2
}
},
"checkId":"144165083478491226"
},
"1":{
"countries":{
"AIA":{
"count":2
}
},
"checkId":"144165083478491106"
}
}
From the comments it looks like you could use Map()
object1 = { "0": { countries: { BDI: { count: 1, }, IRN: { count: 1, }, }, checkId: "16835659691517226105", }, "1": { countries: { ZAF: { count: 2, }, }, checkId: "144165083478491226", }, };
object2 = { "0": { countries: { AIA: { count: 2, }, }, checkId: "144165083478491106", }, "1": { countries: { BDI: { count: 1, }, IRN: { count: 1, }, ATA: { count: 5, }, }, checkId: "16835659691517226105", }, };
map = new Map();
arr = [Object.values(object1), Object.values(object2)].flat();
result = [
...arr
.reduce((r, o) => {
const dupli = r.get(o.checkId);
dupli ? r.delete(o.checkId) : r.set(o.checkId, o);
return r;
}, new Map())
.values(),
];
console.log(result);

how to change value of all nodes of json array

I have a json array with different key values and need to add a ServerUrl to the beginning of all node values using a loop without writing multiple statements to do that by using javascript:
"Urls": [
{ "getCar": "/getAllCars" },
{ "getPerson": "/getAllPersons" },
{ "getBook": "/getAllBooks" }
],
"ServerUrl": "http://192.168.1.1:3000"
The expected result must be:
"Urls": [
{ "getCar": "http://192.168.1.1:3000/getAllCars" },
{ "getPerson": "http://192.168.1.1:3000/getAllPersons" },
{ "getBook": "http://192.168.1.1:3000/getAllBooks" }
],
Any advice would be appreciated.
You can use map to map your objects to new objects. Those objects have a single property, which you can get with Object.keys. The new object can get that same property name using the computed property name feature:
var obj = {
"Urls": [
{ "getCar": "/getAllCars" },
{ "getPerson": "/getAllPersons" },
{ "getBook": "/getAllBooks" }
],
"ServerUrl": "http://192.168.1.1:3000"
};
var urls = obj.Urls.map(o => Object.keys(o).map(k => ({ [k]: obj.ServerUrl + o[k] }))[0]);
console.log(urls);
const jsonVal = {
"Urls": [
{ "getCar": "/getAllCars" },
{ "getPerson": "/getAllPersons" },
{ "getBook": "/getAllBooks" }
],
"ServerUrl": "http://192.168.1.1:3000"
}
const result = jsonVal.Urls.map(val =>
Object.keys(val).reduce((resultObj, endpointKey) => {
resultObj[endpointKey] = `${jsonVal.ServerUrl}${val[endpointKey]}`;
return resultObj;
}, {})
);
Try (where your data are in d)
d.Urls.forEach( (x,i,a,k=Object.keys(x)[0]) => x[k] = d.ServerUrl + x[k]);
let d = {
"Urls": [
{ "getCar": "/GetAllGroupCustomers" },
{ "getPerson": "/getAllItems" },
{ "getBook": "/GetAllCustomers" }
],
"ServerUrl": "http://192.168.1.1:3000"
}
d.Urls.forEach( (x,i,a,k=Object.keys(x)[0]) => x[k] = d.ServerUrl + x[k]);
console.log(d);
A version that modifies your own object
var obj = {
"Urls": [
{ "getCar": "/getAllCars" },
{ "getPerson": "/getAllPersons" },
{ "getBook": "/getAllBooks" }
],
"ServerUrl": "http://192.168.1.1:3000"
};
obj.Urls.forEach(o => o[Object.keys(o)[0]] = `${obj.ServerUrl}${o[Object.keys(o)[0]]}`);
console.log(obj);

Lodash - DifferenceBy with different identity

I have the following array:
[
{
id: 1
},
{
id: 2
},
{
id: 3
},
{
id: 4
}
]
Every 5 seconds my application receives a new array and I need to compare the difference between the next one...
So the next array is:
[
{
conversation_id: 1
},
{
conversation_id: 2
},
{
conversation_id: 4
}
]
Considering that identity is different. How can I compare with the previous and get an array with the excluded item?
[
{
id: 3
}
]
Use _.differenceWith():
const prev = [{"id":1},{"id":2},{"id":3},{"id":4}]
const next = [{"conversation_id":1},{"conversation_id":2},{"conversation_id":4}]
const diff = _.differenceWith(prev, next, ({ id }, { conversation_id }) => _.eq(id, conversation_id))
console.log(diff)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>
I think you can use mix of javascript and lodash to solve this problem.
var arrayList = [
{
id: 1
},
{
id: 2
},
{
id: 3
},
{
id: 4
}
];
var conv_array = [
{
conversation_id: 1
},
{
conversation_id: 2
},
{
conversation_id: 4
}
];
var itemsNotInArray = [];
arrayList.filter(function (item) {
if (!_.find(conv_array, {conversation_id: item.id })) {
console.log("not in array", item);
itemsNotInArray.push(item);
}
});
console.log("result you expected", itemsNotInArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Filter the first array and compare each value till you find a missing id :
var array1 = [{
id: 1
},
{
id: 2
},
{
id: 3
},
{
id: 4
}
];
var array2 = [{
conversation_id: 1
},
{
conversation_id: 2
},
{
conversation_id: 4
}
];
var test = array1.filter(
conv => !array2.find(
id => id.conversation_id === conv.id
)
);
console.log(test)
From lodash documentation, the third argument to differenceBy is
[iteratee=_.identity] (Function): The iteratee invoked per element.
Based on this, you can use
var current = [
{
id: 1
},
{
id: 2
},
{
id: 3
},
{
id: 4
}
];
and
var next = [
{
conversation_id: 1
},
{
conversation_id: 2
},
{
conversation_id: 4
}
];
then
var difference = _.differenceBy(current, next, function(obj) {
return obj.id || obj.conversation_id;
});
Or shortened with an arrow function:
var difference = _.differenceBy(current, next, (x) => x.id || x.conversation_id)

Categories

Resources