I have such object:
const countriesList = {
NAC: {
name: 'NAC'
},
LEVANT: {
name: 'Levant'
},
GCC: {
name: 'Gulf Cooperation Council',
iso2: 'GC',
code: '96'
},
AF: {
name: "Afghanistan",
iso2: "AF",
code: "93"
},
AL: {
name: "Albania",
iso2: "AL",
code: "355"
},
}
It's object, not array and it's important. I want to create new array, which is gonna look like that:
const result = [
{NAC: 'NAC'},
{LEVANT: 'Levant'},
{GCC: 'Gulf Cooperation Council'},
{AF: "Afghanistan"},
{AL: "Albania"}
]
I was trying to do something like that:
for (let value in countriesList) {
let temp = {
value: countriesList[value]['name']
}
this.countries.push(temp)
temp = {}
}
But instead of keys in array of objects I got value. How can I do that?
Thanks for answers!
You can map over Object.entries.
const countriesList = {
NAC: {
name: 'NAC'
},
LEVANT: {
name: 'Levant'
},
GCC: {
name: 'Gulf Cooperation Council',
iso2: 'GC',
code: '96'
},
AF: {
name: "Afghanistan",
iso2: "AF",
code: "93"
},
AL: {
name: "Albania",
iso2: "AL",
code: "355"
},
}
const res = Object.entries(countriesList).map(([key, {name}])=>({[key]: name}));
console.log(res);
Just use Object.keys then map to the name property:
Object.keys(countriesList).map(x => ({[x]: countriesList[x].name}))
You can Create and similar Array of Object with all the Keys.
const countryList = Object.entries(countriesList).map((e) => ( { [e[0]]: e[1] } ));
This Will Return Like This
[
{
NAC: {
name: 'NAC'
},
LEVANT: {
name: 'Levant'
},
GCC: {
name: 'Gulf Cooperation Council',
iso2: 'GC',
code: '96'
},
AF: {
name: "Afghanistan",
iso2: "AF",
code: "93"
},
AL: {
name: "Albania",
iso2: "AL",
code: "355"
},
}
]
Related
This question already has answers here:
Filter array of objects with another array of objects
(11 answers)
Closed 1 year ago.
const items = [[{name:"p2"},{name:"p3"}, {name:"p7"},{name:"p9"},{name:"p1"}],[{name:"p6"}, {name:"p3"},{name:"p7"}, {name:"p9"},{name:"p2"}],[{name:"p3"},{name:"p6"}, {name:"p7"},{name:"p9"},{name:"p4"}],[{name:"p2"}, {name:"p3"},{name:"p1"}, {name:"p9"},{name:"p6"}]]
const findObj = [{name:"p1"},{name:"p2"},{name:"p6"}]
Find the child array of sets which have all three element from findobj object
You can easily achieve the result using filter, Set and reduceas:
const items = [
[
{ name: "p2" },
{ name: "p3" },
{ name: "p7" },
{ name: "p9" },
{ name: "p1" },
],
[
{ name: "p6" },
{ name: "p3" },
{ name: "p7" },
{ name: "p9" },
{ name: "p2" },
],
[
{ name: "p3" },
{ name: "p6" },
{ name: "p7" },
{ name: "p9" },
{ name: "p4" },
],
[
{ name: "p2" },
{ name: "p3" },
{ name: "p1" },
{ name: "p9" },
{ name: "p6" },
],
];
const findObj = [{ name: "p1" }, { name: "p2" }, { name: "p6" }];
const set = new Set(findObj.map((o) => o.name));
const result = items.filter((arr) => {
const remain = arr.reduce((acc, curr) => {
if (set.has(curr.name)) acc.add(curr.name);
return acc;
}, new Set());
return remain.size === set.size;
});
console.log(result);
const items = [[{name:"p2"},{name:"p3"}, {name:"p7"},{name:"p9"},{name:"p1"}],[{name:"p6"}, {name:"p3"},{name:"p7"}, {name:"p9"},{name:"p2"}],[{name:"p3"},{name:"p6"}, {name:"p7"},{name:"p9"},{name:"p4"}],[{name:"p2"}, {name:"p3"},{name:"p1"}, {name:"p9"},{name:"p6"}]]
const findObj = [{name:"p1"},{name:"p2"},{name:"p6"}]
const result = items.filter(item=>{
const childItem = item.map(childItem=>childItem.name);
let allExist=true;
findObj.forEach(obj=>{
if(!childItem.includes(obj.name)){
allExist=false;
}
})
return allExist;
})
console.log(result)
Using filter and get all names from each item by using map .map(prop=>prop.name) or more simple with destructuring .map(({name})=>name) and filter items that names are included in findObj
const items = [[{name:"p2"},{name:"p3"}, {name:"p7"},{name:"p9"},{name:"p1"}],[{name:"p6"}, {name:"p3"},{name:"p7"}, {name:"p9"},{name:"p2"}],[{name:"p3"},{name:"p6"}, {name:"p7"},{name:"p9"},{name:"p4"}],[{name:"p2"}, {name:"p3"},{name:"p1"}, {name:"p9"},{name:"p6"}]]
const findObj = [{name:"p1"},{name:"p2"},{name:"p6"}]
const result = items.filter(item=>{
const arrProp = item.map(prop=>prop.name)
const filtProp = findObj.map(({name})=>name)
return filtProp.every(x=>arrProp.includes(x));
})
console.log(result)
Is there any way i can filter files with given extension and then further filter them
for eg: I have .txt extension and i want to get all my .txt from an array
file=
[ "animal_bio.txt",
"xray.pdf",
"fish_bio.txt",
"mammal_doc.txt",
"human_bio.txt",
"machine.jpg"
]
filtered output contain all .txt extension and further it should contain all the files which have _bio.txt name in it.
so output look like
futherFile=
[ "human_bio.txt",
"fish_bio.txt",
"animal_bio.txt"
]
You can use String.protytype.endsWith function to compare the strings with your extension
const file =
[ "animal_bio.txt",
"xray.pdf",
"fish_bio.txt",
"mammal_doc.txt",
"human_bio.txt",
"machine.jpg"
]
result = file.filter((fileName) => fileName.endsWith("_bio.txt"));
console.log(result)
You can use the Array.filter method and use the String.endsWith method to filter. An example -
// List of files
file = ["animal_bio.txt",
"xray.pdf",
"fish_bio.txt",
"mammal_doc.txt",
"human_bio.txt",
"machine.jpg"
]
// Filtering by extension
file.filter(x => x.endsWith(".txt"));
Hope it helped :)
You can easily achieve this result using reduce and match
When matching for the doc or bio, You can even restrict more to get the string only if _doc.txt is at end of the string using Regular expression /_bio.txt$/
const arr = [
{
id: "1",
name: "animal_bio.txt",
},
{
id: "2",
name: "xray.pdf",
},
{
id: "3",
name: "animal_doc.txt",
},
{
id: "4",
name: "fish_doc.txt",
},
{
id: "5",
name: "flower_petals.jpg",
},
{
id: "5",
name: "plant_roots.jpg",
},
{
id: "6",
name: "human_image.jpg",
},
{
id: "7",
name: "human_bio.txt",
},
{
id: "8",
name: "mammal_doc.txt",
},
];
const result = arr.reduce((acc, { name }) => {
if (name.match(/\.txt$/)) {
if (name.match(/_bio/)) {
acc[0].push(name);
} else {
acc[1].push(name);
}
}
return acc;
},
[[], []]
);
console.log(result);
Then you can get the element containing doc and bio using array destructuring as
const [bioArr, docArr] = result;
console.log(bioArr);
console.log(docArr);
const arr = [
{
id: "1",
name: "animal_bio.txt",
},
{
id: "2",
name: "xray.pdf",
},
{
id: "3",
name: "animal_doc.txt",
},
{
id: "4",
name: "fish_doc.txt",
},
{
id: "5",
name: "flower_petals.jpg",
},
{
id: "5",
name: "plant_roots.jpg",
},
{
id: "6",
name: "human_image.jpg",
},
{
id: "7",
name: "human_bio.txt",
},
{
id: "8",
name: "mammal_doc.txt",
},
];
const result = arr.reduce(
(acc, { name }) => {
if (name.match(/\.txt$/)) {
if (name.match(/_bio/)) {
acc[0].push(name);
} else {
acc[1].push(name);
}
}
return acc;
},
[[], []]
);
const [bioArr, docArr] = result;
console.log(bioArr);
console.log(docArr);
you can use filter function from ES6 like:
const txtFile = file.filter((item) => (item.split('_'))[1] === 'bio.txt')
What I need is an array of property values, recursively collected from an array of objects, this is what I mean:
const regions = [{
name: 'Europe',
subRegions: [{
name: 'BeNeLux',
territories: [{
code: 'NL',
name: 'Netherlands'
}, {
code: 'DE',
name: 'Germany'
}, {
code: 'LU',
name: 'Luxembourgh'
}]
}],
territories: [{
code: 'UK',
name: 'United Kingdom'
}, {
code: 'AL',
name: 'Albania'
}, {
code: 'ZW',
name: 'Switzerland'
}]
}]
I want to get an array of all the country codes in the regions array.
So like:
const expectedOutput = ['NL', 'DE', 'LU', 'AL', 'ZW', 'UK'];
This what I have tried, which partly works but it's not collecting it correctly (I'm also very curious for exploring different / functional setups to solve this problem)
const getAllTerritoryCodesFromRegions = regions => {
return regions
.reduce(function r (output, region) {
if (region?.subRegions?.length) {
output.subRegions = region.subRegions.reduce(r, output)
}
if (region?.territories?.length) {
output = [
...output,
...region.territories.map(t => t.code)
]
}
return output
}, [])
}
You could reduce the array by looking for arrays and return the codes.
function getCodes(array) {
return array.reduce((r, o) => {
if ('code' in o) {
r.push(o.code);
return r;
}
Object.values(o).forEach(v => {
if (Array.isArray(v)) r.push(...getCodes(v));
});
return r;
}, []);
}
const
regions = [{ name: 'Europe', subRegions: [{ name: 'BeNeLux', territories: [{ code: 'NL', name: 'Netherlands' }, { code: 'DE', name: 'Germany' }, { code: 'LU', name: 'Luxembourgh' }] }], territories: [{ name: 'United Kingdom', code: 'UK' }, { name: 'AL', code: 'Albania' }, { name: 'ZW', code: 'Switzerland' }] }],
codes = getCodes(regions);
console.log(codes);
Assuming that the code properties should always contain the country codes:
It would probably be easier to create one array on the first call, which gets recursively passed down as a parameter, than to create an array for every call and try to combine it later. Then you just need to forEach over the regions and territories and push the code to that array:
const regions = [{
name: 'Europe',
subRegions: [{
name: 'BeNeLux',
territories: [{
code: 'NL',
name: 'Netherlands'
}, {
code: 'DE',
name: 'Germany'
}, {
code: 'LU',
name: 'Luxembourgh'
}]
}],
territories: [{
name: 'United Kingdom',
code: 'UK'
}, {
code: 'AL',
name: 'Albania'
}, {
code: 'ZW',
name: 'Switzerland'
}]
}];
const getAllTerritoryCodesFromRegions = (regions, allCodes=[]) => {
regions.forEach(({ territories, subRegions }) => {
if (territories) {
territories.forEach(({ code }) => {
allCodes.push(code);
});
}
if (subRegions) {
getAllTerritoryCodesFromRegions(subRegions, allCodes);
}
});
return allCodes;
};
console.log(
getAllTerritoryCodesFromRegions(regions)
);
You could do it with a recursive method
const getAllTerritoryCodesFromRegions = array => {
const output = [];
array.forEach(item => {
for (const key in item) {
if (key === 'code') {
output.push(item[key]);
} else if (item.hasOwnProperty(key) && Array.isArray(item[key])) {
const childOutput = getAllTerritoryCodesFromRegions(item[key]);
output.push(...childOutput);
}
}
});
return output;
}
You can find a working example here jsfiddle. However in the dataset from your example you messed up some names and codes.
i have an array like this
var data = [
{
name: "Movies", info: "category_name",
content: [
{ name: "Interstellar", info: "category_data" },
{ name: "Dark Knight", info: "category_data" },
]
},
{
name: "Music", info: "category_name",
content: [
{ name: "Adams", info: "category_data" },
{ name: "Nirvana", info: "category_data" },
]
},
{
name: "Places", info: "category_name",
content: [
{ name: "Jordan", info: "category_data" },
{ name: "Punjab", info: "category_data" },
]
},
]
and a want to transform it into like this
var transformedArray= [
{ name: "Movies", info: "category_name" },
{ name: "Interstellar", info: "category_data" },
{ name: "Dark Knight", info: "category_data" },
{ name: "Music", info: "category_name" },
{ name: "Adams", info: "category_data" },
{ name: "Nirvana", info: "category_data" },
{ name: "Places", info: "category_name" },
{ name: "Jordan", info: "category_data" },
{ name: "Punjab", info: "category_data" },
]
i dont know what is the keyword suitable for this case ,
i have tried mapping it into new array but it's not same like i expected
var newArr = []
var manipulate = data.map(item => {
return (
newArr.push(item),
new1.map(items => {
return (
new1.push(items)
)
})
)
})
then how to manipulate "data" into "transformedArray"
Use Array.prototype.flatMap(). If your browser or version of Node.js does not yet natively support this function, you can include a simple polyfill below, based on the specification:
if (!Array.prototype.flatMap) {
Object.defineProperty(Array.prototype, 'flatMap', {
configurable: true,
writable: true,
value: function flatMap (callback, thisArg = undefined) {
return this.reduce((array, ...args) => {
const element = callback.apply(thisArg, args);
if (Array.isArray(element)) array.push(...element);
else array.push(element);
return array;
}, []);
}
});
}
const data = [{name:'Movies',info:'category_name',content:[{name:'Interstellar',info:'category_data'},{name:'Dark Knight',info:'category_data'}]},{name:'Music',info:'category_name',content:[{name:'Adams',info:'category_data'},{name:'Nirvana',info:'category_data'}]},{name:'Places',info:'category_name',content:[{name:'Jordan',info:'category_data'},{name:'Punjab',info:'category_data'}]}];
const transformedArray = data.flatMap(({ content, ...o }) => [o, ...content]);
console.log(transformedArray);
You could do this using reduce method and spread syntax ....
var data = [{"name":"Movies","info":"category_name","content":[{"name":"Interstellar","info":"category_data"},{"name":"Dark Knight","info":"category_data"}]},{"name":"Music","info":"category_name","content":[{"name":"Adams","info":"category_data"},{"name":"Nirvana","info":"category_data"}]},{"name":"Places","info":"category_name","content":[{"name":"Jordan","info":"category_data"},{"name":"Punjab","info":"category_data"}]}]
const result = data.reduce((r, {content, ...rest}) => {
r.push({...rest}, ...content)
return r;
}, []);
console.log(result);
You can also use concat and reduce instead of spread syntax.
var data = [{"name":"Movies","info":"category_name","content":[{"name":"Interstellar","info":"category_data"},{"name":"Dark Knight","info":"category_data"}]},{"name":"Music","info":"category_name","content":[{"name":"Adams","info":"category_data"},{"name":"Nirvana","info":"category_data"}]},{"name":"Places","info":"category_name","content":[{"name":"Jordan","info":"category_data"},{"name":"Punjab","info":"category_data"}]}]
const result = data.reduce((r, {content, ...rest}) => r.concat(rest, content), []);
console.log(result);
What I need is an array of property values, recursively collected from an array of objects, this is what I mean:
const regions = [{
name: 'Europe',
subRegions: [{
name: 'BeNeLux',
territories: [{
code: 'NL',
name: 'Netherlands'
}, {
code: 'DE',
name: 'Germany'
}, {
code: 'LU',
name: 'Luxembourgh'
}]
}],
territories: [{
code: 'UK',
name: 'United Kingdom'
}, {
code: 'AL',
name: 'Albania'
}, {
code: 'ZW',
name: 'Switzerland'
}]
}]
I want to get an array of all the country codes in the regions array.
So like:
const expectedOutput = ['NL', 'DE', 'LU', 'AL', 'ZW', 'UK'];
This what I have tried, which partly works but it's not collecting it correctly (I'm also very curious for exploring different / functional setups to solve this problem)
const getAllTerritoryCodesFromRegions = regions => {
return regions
.reduce(function r (output, region) {
if (region?.subRegions?.length) {
output.subRegions = region.subRegions.reduce(r, output)
}
if (region?.territories?.length) {
output = [
...output,
...region.territories.map(t => t.code)
]
}
return output
}, [])
}
You could reduce the array by looking for arrays and return the codes.
function getCodes(array) {
return array.reduce((r, o) => {
if ('code' in o) {
r.push(o.code);
return r;
}
Object.values(o).forEach(v => {
if (Array.isArray(v)) r.push(...getCodes(v));
});
return r;
}, []);
}
const
regions = [{ name: 'Europe', subRegions: [{ name: 'BeNeLux', territories: [{ code: 'NL', name: 'Netherlands' }, { code: 'DE', name: 'Germany' }, { code: 'LU', name: 'Luxembourgh' }] }], territories: [{ name: 'United Kingdom', code: 'UK' }, { name: 'AL', code: 'Albania' }, { name: 'ZW', code: 'Switzerland' }] }],
codes = getCodes(regions);
console.log(codes);
Assuming that the code properties should always contain the country codes:
It would probably be easier to create one array on the first call, which gets recursively passed down as a parameter, than to create an array for every call and try to combine it later. Then you just need to forEach over the regions and territories and push the code to that array:
const regions = [{
name: 'Europe',
subRegions: [{
name: 'BeNeLux',
territories: [{
code: 'NL',
name: 'Netherlands'
}, {
code: 'DE',
name: 'Germany'
}, {
code: 'LU',
name: 'Luxembourgh'
}]
}],
territories: [{
name: 'United Kingdom',
code: 'UK'
}, {
code: 'AL',
name: 'Albania'
}, {
code: 'ZW',
name: 'Switzerland'
}]
}];
const getAllTerritoryCodesFromRegions = (regions, allCodes=[]) => {
regions.forEach(({ territories, subRegions }) => {
if (territories) {
territories.forEach(({ code }) => {
allCodes.push(code);
});
}
if (subRegions) {
getAllTerritoryCodesFromRegions(subRegions, allCodes);
}
});
return allCodes;
};
console.log(
getAllTerritoryCodesFromRegions(regions)
);
You could do it with a recursive method
const getAllTerritoryCodesFromRegions = array => {
const output = [];
array.forEach(item => {
for (const key in item) {
if (key === 'code') {
output.push(item[key]);
} else if (item.hasOwnProperty(key) && Array.isArray(item[key])) {
const childOutput = getAllTerritoryCodesFromRegions(item[key]);
output.push(...childOutput);
}
}
});
return output;
}
You can find a working example here jsfiddle. However in the dataset from your example you messed up some names and codes.