Related
I have an array like this.
let arr = [
{
"ABBRIVATION":"ISB",
"name":"ISLAMABAD",
},
{
"ABBRIVATION":"RAW",
"name":"PINDI",
},
{
"ABBRIVATION":"SWB",
"name":"SWABI",
},
{
"ABBRIVATION":"AQ",
"name":"AQEEL",
},
]
I want to change it to like this
let me explain it a little. I want to assign the abbreviation directly to the name and the iterate through that array
let outout = [
{
"ISB":"ISLAMABAD"
},
{
"RAW":"ISLAMABAD"
},
{
"SWB":"SWABI"
},
{
"AQ":"AQEEL"
},
]
that is what I tried
let k = arr.map((item) => {
return item.ABB = item.name
})
console.log(k)
and here is the output
[ 'ISLAMABAD', 'PINDI', 'SWABI', 'AQEEL' ]
Here you go, use array map, simples
let arr = [
{
"ABBRIVATION":"ISB",
"name":"ISLAMABAD",
},
{
"ABBRIVATION":"RAW",
"name":"PINDI",
},
{
"ABBRIVATION":"SWB",
"name":"SWABI",
},
{
"ABBRIVATION":"AQ",
"name":"AQEEL",
},
]
let outout = arr.map(({ABBRIVATION, name}) => ({[ABBRIVATION]: name}));
console.log(outout);
Nothing more than a simple Array.prototype.map() needed.
let arr = [
{
ABBRIVATION: "ISB",
name: "ISLAMABAD",
},
{
ABBRIVATION: "RAW",
name: "PINDI",
},
{
ABBRIVATION: "SWB",
name: "SWABI",
},
{
ABBRIVATION: "AQ",
name: "AQEEL",
},
];
const result = arr.map(e => ({ [e.ABBRIVATION]: e.name }));
console.log(result);
map over the array of objects (map returns a new array) and assign the name to a new key defined by the abbreviation.
You code works the way it does because item.ABB is undefined, but you're also assigning item.name to it which does get returned, so you just get an array of names returned.
const arr=[{ABBRIVATION:"ISB",name:"ISLAMABAD"},{ABBRIVATION:"RAW",name:"PINDI"},{ABBRIVATION:"SWB",name:"SWABI"},{ABBRIVATION:"AQ",name:"AQEEL"}];
const out = arr.map(obj => {
return { [obj.ABBRIVATION]: obj.name };
});
console.log(out);
Hi I have seen people answer, but most of them use the map function, I provide some other solutions, hoping to expand the thinking
Use forEach function
const datas = [
{
"ABBRIVATION":"ISB",
"name":"ISLAMABAD",
},
{
"ABBRIVATION":"RAW",
"name":"PINDI",
},
{
"ABBRIVATION":"SWB",
"name":"SWABI",
},
{
"ABBRIVATION":"AQ",
"name":"AQEEL",
}
];
datas.forEach((obj, i, arr) => {
const{'ABBRIVATION':k, 'name':v} = obj;
arr[i] = {[k]:v};
});
console.log(datas);
Use flatMap function
const datas = [
{
"ABBRIVATION":"ISB",
"name":"ISLAMABAD",
},
{
"ABBRIVATION":"RAW",
"name":"PINDI",
},
{
"ABBRIVATION":"SWB",
"name":"SWABI",
},
{
"ABBRIVATION":"AQ",
"name":"AQEEL",
}
];
const result = datas.flatMap(obj => {
const {'ABBRIVATION':k, 'name':v} = obj;
return {[k]:v};
});
console.log(result);
this is how you suppose to do it.
arr.reduce((d, c)=>([...d, {[c.ABBRIVATION]: c.name}]),[])
let arr = [
{
"ABBRIVATION":"ISB",
"name":"ISLAMABAD",
},
{
"ABBRIVATION":"RAW",
"name":"PINDI",
},
{
"ABBRIVATION":"SWB",
"name":"SWABI",
},
{
"ABBRIVATION":"AQ",
"name":"AQEEL",
},
]
console.log(arr.reduce((data, current)=>([...data, {[current.ABBRIVATION]: current.name}]),[]))
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.
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);
I have the following data structure:
[
{
"performanceDatetime": "2020-01-28T08:00:00Z",
"waivers": [
{
"ticketId": "66288",
},
]
},
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [
{
"ticketId": "63152",
},
{
"ticketId": "66113",
}
]
},
{
"performanceDatetime": "2020-01-28T09:00:00Z",
"waivers": [
{
"ticketId": "62667",
},
]
}
]
i.e., a list of objects. Inside these objects, there is another list: waivers. My question is, how would I filter the list waivers inside the list of objects, such that, if I filtered by, e.g., a ticketID of 63152, I'd receive the following returned:
[
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [
{
"ticketId": "63152",
}
]
}
]
Assuming the original data structure is stored as this.activeSurfersWaivers, I have tried the following:
const todaysWaivers = this.activeSurfersWaivers.filter((surfersWaivers) => {
surfersWaivers.waivers.filter((surferWaiver) => {
return (surferWaiver.ticketId.indexOf(this.searchedTicketID) >= 0);
});
});
Which returns an empty array for a value of this.searchedTicketID of 63152. Any pro-tips on filtering this awkward data structure would be greatly appreciated!
This is what I would do if I had to rush it:
const data = [{
"performanceDatetime": "2020-01-28T08:00:00Z",
"waivers": [{
"ticketId": "66288",
}, ]
},
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [{
"ticketId": "63152",
},
{
"ticketId": "66113",
}
]
},
{
"performanceDatetime": "2020-01-28T09:00:00Z",
"waivers": [{
"ticketId": "62667",
}, ]
}
]
const idToFind = "63152";
const matchingEntries = data.filter(entry => entry.waivers.some(el => el.ticketId === idToFind));
matchingEntries.forEach(entry => entry.waivers = entry.waivers.filter(el => el.ticketId === idToFind));
console.log(matchingEntries);
This returns
[
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [
{
"ticketId": "63152"
}
]
}
]
Here is how you do it:
https://codepen.io/v08i/pen/KKwYrRp
<div id="test1">
</div>
<div id="test2">
</div>
let arr = [
{
"performanceDatetime": "2020-01-28T08:00:00Z",
"waivers": [
{
"ticketId": "66288",
},
]
},
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [
{
"ticketId": "63152",
},
{
"ticketId": "66113",
}
]
},
{
"performanceDatetime": "2020-01-28T09:00:00Z",
"waivers": [
{
"ticketId": "62667",
},
]
}
]
function findItem(id) {
return arr.find((item) => {
return item.waivers.some((waiver) => { return waiver.ticketId == id});
});
}
document.getElementById('test1').innerHTML = JSON.stringify(findItem('63152'));
document.getElementById('test2').innerHTML = JSON.stringify(findItem('62667'));
console.log(findItem('63152'));
console.log(findItem('62667'));
You are actually very close. You'll want to check if the second filter yields any results:
data = [
{
"performanceDatetime": "2020-01-28T08:00:00Z",
"waivers": [
{
"ticketId": "66288",
},
]
},
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [
{
"ticketId": "63152",
},
{
"ticketId": "66113",
}
]
},
{
"performanceDatetime": "2020-01-28T09:00:00Z",
"waivers": [
{
"ticketId": "62667",
},
]
}
];
const filter = ticket => {
return data.filter(entry => {
return entry.waivers.some(waiver => waiver.ticketId === ticket)
}).map(entry => {
entry.waivers = entry.waivers.filter(waiver => waiver.ticketId === ticket);
return entry;
});
};
console.log(filter("63152"));
I hope this solution is what you are looking for. It takes care of instances where
there are multiple waivers array entries.
var dataStructure =
[
{
"performanceDatetime": "2020-01-28T08:00:00Z",
"waivers": [
{
"ticketId": "66288",
},
]
},
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [
{
"ticketId": "63152",
},
{
"ticketId": "66113",
}
]
},
{
"performanceDatetime": "2020-01-28T09:00:00Z",
"waivers": [
{
"ticketId": "62667",
},
]
}
];
function filterDataStructureByWaiverTicketId(ticketId)
{
return dataStructure.filter(function (value, index, array)
{
//find index in the "waivers" array where ticketId occurs
var waiverIndex = value.waivers.reduce(function(a, e, i)
{
if (e.ticketId === ticketId)
{
a.push(i);
}
return a;
}, []);
if(waiverIndex.length > 0)//if a match exists
{ //remove everything in the "waivers" array that does not match
var newWaivers = value.waivers.filter(function (value, index, array)
{
return value.ticketId === ticketId;
});
value.waivers = newWaivers;//replace the old waivers array with the new one that matches
return value.waivers[0].ticketId === ticketId;//tadaa...
}
});
}
Usage example:
Example 1:
var newdatastructure = filterDataStructureByWaiverTicketId("66113");/*
newdatastructure[0].performanceDatetime //returns "2020-01-28T08:30:00Z"
newdatastructure[0].waivers[0].ticketId //returns "66113"
newdatastructure //returns
[
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [
{
"ticketId": "66113",
}
]
}
]*/
Example 2:
var newdatastructure = filterDataStructureByWaiverTicketId("63152");/*
newdatastructure[0].performanceDatetime //returns "2020-01-28T08:30:00Z"
newdatastructure[0].waivers[0].ticketId //returns "63152"
newdatastructure // returns
[
{
"performanceDatetime": "2020-01-28T08:30:00Z",
"waivers": [
{
"ticketId": "63152",
}
]
}
]*/
Example 3:
var newdatastructure = filterDataStructureByWaiverTicketId("66288");/*
newdatastructure[0].performanceDatetime //returns "2020-01-28T08:00:00Z"
newdatastructure[0].waivers[0].ticketId //returns "66288"
newdatastructure //returns
[
{
"performanceDatetime": "2020-01-28T08:00:00Z",
"waivers": [
{
"ticketId": "66288",
}
]
}
]*/
Although these techniques are very similar to those in the answer by connexo, I find it cleaner to make a reusable function. This is what I came up with:
const matchingPerformances = (data, id) => data
.filter (({waivers}) => waivers .some (({ticketId}) => ticketId == id))
.reduce ((a, {waivers, ... r}) => [
... a,
{... r, waivers: waivers .filter (({ticketId}) => ticketId == id)}
], [])
const data = [{performanceDatetime: "2020-01-28T08: 00: 00Z", waivers: [{ticketId: "66288"}]}, {performanceDatetime: "2020-01-28T08: 30: 00Z", waivers: [{ticketId: "63152"}, {ticketId: "66113"}]}, {performanceDatetime: "2020-01-28T09: 00: 00Z", waivers: [{ticketId: "62667"}]}]
console .log (matchingPerformances (data, "63152"))
If I wanted to clean up some duplication, I might add a helper function:
const ticketMatch = (id) => ({ticketId}) => ticketId == id
const matchingPerformances = (data, id) => data
.filter (({waivers}) => waivers .some (ticketMatch (id)))
.reduce ((a, {waivers, ... r}) => [
... a,
{... r, waivers: waivers .filter (ticketMatch (id))}
], [])
While this could be done in a single reduce call, I think that would end up being much harder code to understand.
UPDATE: Adding multiple ways to do.
Using reduce method. (find_item method)
Using for of loop. (find_item2 method)
const find_item = (arr, searchId) =>
arr.reduce((acc, curr) => {
const waivers = curr.waivers.filter(waiver => waiver.ticketId === searchId);
return waivers.length > 0 ? [{ ...acc, ...curr, waivers }] : [...acc];
}, []);
const find_item2 = (arr, searchId) => {
for (let curr of arr) {
const waivers = curr.waivers.filter(waiver => waiver.ticketId === searchId);
if (waivers.length > 0) {
return [{ ...curr, waivers }];
}
}
return [];
};
const arr = [
{
performanceDatetime: "2020-01-28T08:00:00Z",
waivers: [
{
ticketId: "66288"
}
]
},
{
performanceDatetime: "2020-01-28T08:30:00Z",
waivers: [
{
ticketId: "63152"
},
{
ticketId: "66113"
}
]
},
{
performanceDatetime: "2020-01-28T09:00:00Z",
waivers: [
{
ticketId: "62667"
}
]
}
];
const searchId = "66113";
console.log(find_item(arr, searchId));
console.log(find_item2(arr, searchId));
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);