I'm trying to Iterate through a nested array and having trouble extracting the correct value.
My Json FIle
var regions = [
{
"id": 265592,
"longName": "Amsterdam 1",
"name": "ams01",
"statusId": 2,
"regions": [
{
"description": "AMS01 - Amsterdam",
"keyname": "AMSTERDAM",
"sortOrder": 0
}
]
},
{
"id": 814994,
"longName": "Amsterdam 3",
"name": "ams03",
"statusId": 2,
"regions": [
{
"description": "AMS03 - Amsterdam",
"keyname": "AMSTERDAM03",
"sortOrder": 26
}
]
},
{
"id": 1004997,
"longName": "Chennai 1",
"name": "che01",
"statusId": 2,
"regions": [
{
"description": "CHE01 - Chennai ",
"keyname": "CHENNAI",
"sortOrder": 30
}
]
},
I would like to extract only the Key name from the Regions Array into an Array.
MY code which works fine and gives me the output:
const regions3 = []
for (let i = 0; i < regions.length; i++) {
const element = regions[i];
const regions1 = (element.regions)
for (let j = 0; j < regions1.length; j++) {
const element1 = regions1[j];
const element2 = element1.keyname;
regions3.push(element2)
console.log(regions3)
}
}
Output
AMSTERDAM
AMSTERDAM03
CHENNAI
I would like to know if there a faster way to iterate rather than running it into two for loops??
Thank you
You can use Array.flatMap() (not supported in IE/Edge) with Array.map():
const regions = [{"id":265592,"longName":"Amsterdam 1","name":"ams01","statusId":2,"regions":[{"description":"AMS01 - Amsterdam","keyname":"AMSTERDAM","sortOrder":0}]},{"id":814994,"longName":"Amsterdam 3","name":"ams03","statusId":2,"regions":[{"description":"AMS03 - Amsterdam","keyname":"AMSTERDAM03","sortOrder":26}]},{"id":1004997,"longName":"Chennai 1","name":"che01","statusId":2,"regions":[{"description":"CHE01 - Chennai ","keyname":"CHENNAI","sortOrder":30}]}]
const result = regions.flatMap(o =>
o.regions.map(p => p.keyname)
)
console.log(result)
If you can't use Array.flatMap() you can use an external Array.map() and spread the results into Array.concat() instead:
const regions = [{"id":265592,"longName":"Amsterdam 1","name":"ams01","statusId":2,"regions":[{"description":"AMS01 - Amsterdam","keyname":"AMSTERDAM","sortOrder":0}]},{"id":814994,"longName":"Amsterdam 3","name":"ams03","statusId":2,"regions":[{"description":"AMS03 - Amsterdam","keyname":"AMSTERDAM03","sortOrder":26}]},{"id":1004997,"longName":"Chennai 1","name":"che01","statusId":2,"regions":[{"description":"CHE01 - Chennai ","keyname":"CHENNAI","sortOrder":30}]}]
const result = [].concat(...regions.map(o =>
o.regions.map(p => p.keyname)
))
console.log(result)
You can use .map() and destructuring assignment
var regions = [{"id":265592,"longName":"Amsterdam 1","name":"ams01","statusId":2,"regions":[{"description":"AMS01 - Amsterdam","keyname":"AMSTERDAM","sortOrder":0}]},{"id":814994,"longName":"Amsterdam 3","name":"ams03","statusId":2,"regions":[{"description":"AMS03 - Amsterdam","keyname":"AMSTERDAM03","sortOrder":26}]},{"id":1004997,"longName":"Chennai 1","name":"che01","statusId":2,"regions":[{"description":"CHE01 - Chennai ","keyname":"CHENNAI","sortOrder":30}]}];
let res = regions.map(({regions: [{keyname}]}) => keyname);
console.log(res);
Another solution for this is using Array::reduce():
var regions = [{"id":265592,"longName":"Amsterdam1","name":"ams01","statusId":2,"regions":[{"description":"AMS01-Amsterdam","keyname":"AMSTERDAM","sortOrder":0}]},{"id":814994,"longName":"Amsterdam3","name":"ams03","statusId":2,"regions":[{"description":"AMS03-Amsterdam","keyname":"AMSTERDAM03","sortOrder":26}]},{"id":1004997,"longName":"Chennai1","name":"che01","statusId":2,"regions":[{"description":"CHE01-Chennai","keyname":"CHENNAI","sortOrder":30}]}];
let res = regions.reduce(
(acc, curr) => (curr.regions.forEach(x => acc.push(x.keyname)), acc),
[]
);
console.log(res);
Well its pretty much the same thing but using a forEach method or array type in javascript can save you some time. here is an example.
const regions3 = [];
regions.forEach(function(region){
region.regions.forEach(function(subRegion){
regions3.push(subRegion.keyname);
console.log(subRegion.keyname);
})
});
a forEach executes an anonymous function passing each element in array as the argument to the anonymous function
Related
I have the following array
Array["MyArray",
{
"isLoaded":true,
"items":
[{
"id":"4",
"name":"ProductA",
"manufacturer":"BrandA",
"quantity":1,
"price":"25"
},{
"id":"1",
"name":"ProductB",
"manufacturer":"BrandB",
"quantity":5,
"price":"20"
}],
"coupons":null
}
]
I need to load product names and their quantity from the array.
const result = [key, value].map((item) => `${item.name} x ${item.quantity}`);
Here's one possible way to achieve the desired result:
const getProductsAndQuantity = ([k , v] = arr) => (
v.items.map(it => `${it.name} x ${it.quantity}`)
);
How to use it within the context of the question?
localforage.iterate(function(value, key, iterationNumber) {
console.log([key, value]);
const val2 = JSON.parse(value);
if (val2 && val2.items && val2.items.length > 0) {
console.log(val2.items.map(it => `${it.name} x ${it.quantity}`).join(', '))
};
});
How it works?
Among the parameters listed in the question ie, value, key, iterationNumber, only value is required.
The above method accepts the key-value pair as an array (of 2 elements) closely matching the console.log([key, value]); in the question
It uses only v (which is an object). On v, it accesses the prop named items and this items is an Array.
Next, .map is used to iterate through the Array and return each product's name and quantity in the desired/expected format.
Test it out on code-snippet:
const arr = [
"MyArray",
{
"isLoaded": true,
"items": [{
"id": "4",
"name": "ProductA",
"manufacturer": "BrandA",
"quantity": 1,
"price": "25"
}, {
"id": "1",
"name": "ProductB",
"manufacturer": "BrandB",
"quantity": 5,
"price": "20"
}],
"coupons": null
}
];
const getProductsAndQuantity = ([k, v] = arr) => (
v.items.map(
it => `${it.name} x ${it.quantity}`
)
);
console.log(getProductsAndQuantity());
I understood. You should learn about array methods such as map, filter, reduce. Here you go...
const items = [{
"id":"4",
"name":"ProductA",
"manufacturer":"BrandA",
"quantity":1,
"price":"25"
},{
"id":"1",
"name":"ProductB",
"manufacturer":"BrandB",
"quantity":5,
"price":"20"
}];
const result = items.map((item) => `${item.name} x ${item.quantity}`);
console.log(result);
I think I understand the question to say that the input is an array of objects, each containing an array of items. The key is that a nested array requires a nested loop. So, we iterate the objects and their internal items (see the lines commented //outer loop and // inner loop below)
Also, half-guessing from the context, it looks like the that the OP aims to assemble a sort of invoice for each object. First a demo of that, (and see below for the version simplified to exactly what the OP asks)...
const addInvoice = obj => {
let total = 0;
// inner loop
obj.invoice = obj.items.map(i => {
let subtotal = i.quantity * i.price;
total += subtotal
return `name: ${i.name}, qty: ${i.quantity}, unit price: ${i.price}, subtotal: ${subtotal}`
});
obj.invoice.push(`invoice total: ${total}`);
}
const objects = [{
"isLoaded": true,
"items": [{
"id": "4",
"name": "ProductA",
"manufacturer": "BrandA",
"quantity": 1,
"price": "25"
}, {
"id": "1",
"name": "ProductB",
"manufacturer": "BrandB",
"quantity": 5,
"price": "20"
}],
"coupons": null
}]
// outer loop
objects.forEach(addInvoice);
console.log(objects);
If my guess about the goal went to far, just remove the unit price, subtotal and total lines from the invoice function...
const objects = [{
"isLoaded": true,
"items": [{
"id": "4",
"name": "ProductA",
"manufacturer": "BrandA",
"quantity": 1,
"price": "25"
}, {
"id": "1",
"name": "ProductB",
"manufacturer": "BrandB",
"quantity": 5,
"price": "20"
}],
"coupons": null
}]
const summaryString = obj => {
return obj.items.map(i => `${i.name}, ${i.quantity}`);
}
const strings = objects.map(summaryString);
console.log(strings);
There is an array of objects
const data = [{
"name": "08/20/2018",
"id": "name_1"
}, {
"name": "12/23/2018",
"id": "name_2"
}]
and I would like to map this array of objects in order to get just array
["Date 1","08/20/2018","Date 2","12/23/2018"]
I'm trying using .map()
data.map((d, i) =>
`${'Date ' + i}`
d.name
)];
but cannot map name with the first (d) parameter.
Because the input items and output array items aren't one-to-one, you won't be able to use .map. Use reduce instead:
const data = [{
"name": "08/20/2018",
"id": "name_1"
}, {
"name": "12/23/2018",
"id": "name_2"
}];
const output = data.reduce((a, { name }, i) => {
a.push('Date ' + (i + 1), name);
return a;
}, []);
console.log(output);
Or .flatMap:
const data = [{
"name": "08/20/2018",
"id": "name_1"
}, {
"name": "12/23/2018",
"id": "name_2"
}];
const output = data.flatMap(({ name }, i) => (['Date ' + (i + 1), name]));
console.log(output);
(note that since arrays are zero-indexed, you'll have to use i + 1, not i, if you want the first item in the output array to start at 1 instead of 0)
You can't use map since that method produce a new array with the same number of items of the original ones.
However, you can use flatMap (where supported) to achieve the your desired result:
data.flatMap(({name}, i) => [`Date ${i + 1}`, name]);
console.log(data) // [ "Date 1", "08/20/2018", "Date 2", "12/23/2018" ]
Basically flatMap is like calling map and then flat; therefore if from the callback function we returns an array per item, this array will be flattened before returned.
Regular map call would have been produced [[ "Date 1", "08/20/2018"], ["Date 2", "12/23/2018"]] instead.
Try to combine map and flatmap methods in order to achieve desired result:
const data = [{
"name": "08/20/2018",
"id": "name_1"
}, {
"name": "12/23/2018",
"id": "name_2"
}];
const result = data.map((s, i)=> [`Date ${i}`, s.name]).flatMap(f=> f);
console.log(result)
or using flat method:
const data = [{
"name": "08/20/2018",
"id": "name_1"
}, {
"name": "12/23/2018",
"id": "name_2"
}];
const result = data.map((s, i)=> [`Date ${i}`, s.name]).flat(1);
console.log(result)
One line answer using ES2019 Array.flat :
data.map((item,index)=>([`Date${index+1}`,item.name])).flat();
But in my opinion, it is not optimized when there is huge data.
I appreciate above answers but if you still prefer to use .map() method to accomplish your work, you can do it.
Just with an additional use of concat() method with map() method. Let's see how.
I have used ...data,map() statement where ... is used for Array destructuring. More information can be found at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Array_destructuring.
const data = [
{
"name": "08/20/2018",
"id": "name_1"
},
{
"name": "12/23/2018",
"id": "name_2"
}
]
output = new Array() // or just []
output = output.concat(...data.map((obj, index) => [`Date ${index + 1}`, obj.name]))
console.log(output)
// [ 'Date 1', '08/20/2018', 'Date 2', '12/23/2018' ]
Screenshot
I can't set up an algo that counts my occurrences while respecting ESlint's 6 standards in javascript.
My input table is :
[
{
"id": 2,
"name": "Health",
"color": "0190fe"
},
{
"id": 3,
"name": "Agriculture",
"color": "0190fe"
},
{
"id": 1,
"name": "Urban planning",
"color": "0190fe"
},
{
"id": 1,
"name": "Urban planning",
"color": "0190fe"
}
]
And i want to get :
{"Urban planning": 2, "Health": 1, ...}
But that does not work with ESLINT / REACT compilation...
This is my code :
const jsonToIterate = *'MyPreviousInputJson'*
const names = []
jsonToIterate.map(item => (names.push(item.name)))
const count = []
names.forEach(item => {
if (count[item]){
count.push({text: item, value: 1})
} else {
count.forEach(function(top){top.text === item ? top.value =+ 1 : null})
}
})
Thank you so much
Well, you want an object in the end, not an array, so count should be {}. I also wouldn't use map if you're not actually returning anything from the call. You can use reduce for this:
let counts = topicsSort.reduce((p, c, i, a) => {
if (!p.hasOwnProperty(c.name)) p[c.name] = 0;
p[c.name]++;
return p;
}, {});
I'm half exppecting someone to close this as a duplicate because all you've asked for is a frequency counter. But here's an answer anyway:
const jsonToIterate = *'MyPreviousInputJson'*;
const names = {};
jsonToIterate.map(obj => {
if(obj.name in names){
names[obj.name]++
}
else{
names[obj.name] = 1;
}
})
I have an array of objects, wanted to extract values based on the property
let obj = [
{
"name": "USA",
"type": "Required",
},
{
"name": "Australia",
"type": "Discontinued",
},
{
"name": "Austria",
"type": "Optional",
} ,
{
"name": "Argentina",
"type": "Required",
}
]
I have tried to extract from that array of objects based on type like this,
let arr = obj.map((cc)=>{ if(cc["type"] == "Required"){
return cc["type"]
} })
Now, I am getting result as, ["Required", undefined, undefined, "Required"]
But, I am expecting array containing only ["Required", "Required"]
Use filter with map
let arr = obj.filter((cc)=> cc["type"] == "Required").map( cc => cc.type);
You'll want to use filter followed by map, as demonstrated in the other answers:
let arr = obj.filter(cc => cc.type=="Required").map(cc => cc.type);
or the other way round, since your condition is based on the map result anyway:
let arr = obj.map(cc => cc.type).filter(val => val=="Required");
But if you want to do it in one step, I would recommend flatMap :
let arr = obj.flatMap(cc => cc.type=="Required" ? [cc.type] : []);
if you want to iterate once then you could make use of reduce:
obj.reduce((a, e) => e.type === 'Required' ? a.concat(e.type) : a, [])
This question already has answers here:
Iterating Array of Objects in javascript
(9 answers)
Closed 3 years ago.
have file_name.JSON, like
[{"id": 1},{"id": 2},{"id": 3}]
How can I use "for" to get in final:
1,2,3
const file_name = [{
"id": 1
}, {
"id": 2
}, {
"id": 3
}]
for (let i = 0; i <= file_name.length; i++) {
console.log(file_name[i].id);
}
Or maybe another way, not use "for"
To fix your code you need just to change i <= file_name.length to i < file_name.length
const file_name = [{
"id": 1
}, {
"id": 2
}, {
"id": 3
}]
for (let i = 0; i < file_name.length; i++) {
console.log(file_name[i].id);
}
Or for a better and clean code you can use map
const file_name = [{
"id": 1
}, {
"id": 2
}, {
"id": 3
}]
const res = file_name.map(({
id
}) => console.log(id));
Use map
const file_name = [{
"id": 1
}, {
"id": 2
}, {
"id": 3
}]
let arr = file_name.map(e => e.id);
console.log(arr);
let str = file_name.map(e => e.id).join();
console.log(str);
No, you don't have JSON, you have a plain old Javascript array there.
var file_name = [{"id": 1},{"id": 2},{"id": 3}];
var justNumbers = file_name.map(e => e.id);
console.log(justNumbers);