how to return an array inside an array javascript - javascript

i have an array inside an array...how do i return all the values using a for loop in javascript/angular?
for example my json...
[
{
"Name": "element1",
"Attributes": [
{"file":"document.doc"},
{"file":"document2.doc"}
]
},
{
"Name": "element2",
"Attributes": [
{"file":"document3.doc"},
{"file":"document4.doc"}
]
},
{
"Name": "element3",
"Attributes": [
{"file":"document5.doc"},
{"file":"document6.doc"}
]
}
]
having a tough time just returning all the files within attributes...only seem to be getting the first one everytime.
EDIT:
what i have so far..
function getAllFiles() {
for (var i = 0; i < Attributes.file.length; i++) {
return Attributes.file[i];
}
}

One of the methods how to get the desired output, using Array#reduce.
var json = [{Name:"element1",Attributes:[{file:"document.doc"},{file:"document2.doc"}]},{Name:"element2",Attributes:[{file:"document3.doc"},{file:"document4.doc"}]},{Name:"element3",Attributes:[{file:"document5.doc"},{file:"document6.doc"}]}],
res = json.reduce(function(s,a){
s.push(...a.Attributes.map(c => c.file));
return s;
}, []);
console.log(res);
ES5
var json = [{Name:"element1",Attributes:[{file:"document.doc"},{file:"document2.doc"}]},{Name:"element2",Attributes:[{file:"document3.doc"},{file:"document4.doc"}]},{Name:"element3",Attributes:[{file:"document5.doc"},{file:"document6.doc"}]}],
res = json.reduce(function(s,a){
s = s.concat(a.Attributes.map(c => c.file));
return s;
}, []);
console.log(res);

try
var files = [];
json.forEach(function(obj) {
obj.Attributes.forEach(function (f) {
files.push(f.file); })
});
this loops on the json array then on each element's attributes then adds the vilue of file

You could show all the files using Array methods like map and reduce:
var data = [{
"Name": "element1",
"Attributes": [{
"file": "document.doc"
},
{
"file": "document2.doc"
}
]
},
{
"Name": "element2",
"Attributes": [{
"file": "document3.doc"
},
{
"file": "document4.doc"
}
]
},
{
"Name": "element3",
"Attributes": [{
"file": "document5.doc"
},
{
"file": "document6.doc"
}
]
}
];
var files = data.map(function (obj) {
return obj.Attributes.map(function (i) {
return i.file;
});
}).reduce(function (x, y) {
return x.concat(y);
});
console.log(files);
Although Kind user's answer is better:
var data = [{
"Name": "element1",
"Attributes": [{
"file": "document.doc"
},
{
"file": "document2.doc"
}
]
},
{
"Name": "element2",
"Attributes": [{
"file": "document3.doc"
},
{
"file": "document4.doc"
}
]
},
{
"Name": "element3",
"Attributes": [{
"file": "document5.doc"
},
{
"file": "document6.doc"
}
]
}
];
var files = data.reduce(function(acc, val) {
return acc.concat(
val.Attributes.map(function(attribute) {
return attribute.file;
})
);
}, []);
console.log(files);
I renamed some variables so that the code makes more sense (to me).

Something like outerArray.innerArray. in your case arrayName.Attributes should work.

Related

Remove duplicates within the map function

I want to remove duplicates within the map function and I have looked through the different posts on the internet but I am still not finding the solution.
The JSON:
"results": [
{
"data": {
"labels": {
"results": [
{
"name": "tom"
}
]
}
}
},
{
"data": {
"labels": {
"results": [
{
"name": "jerry"
}
]
}
}
},
{
"data": {
"labels": {
"results": [
{
"name": "tom"
}
]
}
}
}
]
The code:
obj.results.map((items) => {
if (items.data.labels.results.length) {
items.data.labels.results.map((result) => {
console.log(result.name);
});
}
});
Result
tom
jerry
tom
Expected Result
tom
jerry
Tried this solution but didn't work
obj.results.map((items) => {
if (items.data.label.results.length) {
items.data.label.results.map((result) => {
console.log(Array.from(new Set(result.name)));
});
}
});
Result from above code
[ 't', 'o', 'm' ]
[ 'j', 'e', 'r', 'r', 'y' ]
[ 't', 'o', 'm' ]
I would use reduce since it is perfect for iterating an array with an accumulative value. In this case, an object.
const x = [{
"data": {
"results": [{
"name": "tom"
}]
}
},
{
"data": {
"results": [{
"name": "jerry"
}]
}
},
{
"data": {
"results": [{
"name": "tom"
}]
}
}
]
var result = Object.values(x.reduce(function(acc, item) {
var name = item.data.results[0].name
// acc[name] = item;
acc[name] = name;
return acc;
}, {}))
console.log(result)
you can achieve this using flatMap to get all name objects and then map to extract the name field. After that a Set to dedupe. [...new Set(..)] converts the Set back to an array
const results = [{
"data": {
"labels": {
"results": [{
"name": "tom"
}, {
"name": "another name"
}]
}
}
}, {
"data": {
"labels": {
"results": [{
"name": "jerry"
}]
}
}
}, {
"data": {
"labels": {
"results": [{
"name": "tom"
}]
}
}
}]
const res = [...new Set(results.flatMap(({data:{labels: {results}}}) => results).map(({name}) => name))]
//alternative
//const res = [...new Set(results.map(({data:{labels: {results}}}) => results).flat().map(({name}) => name))]
console.log(res)

Put JSON data inside another object of the same JSON

I need to put the images that are on "included" into "data:{relationships: { field_imagen: { data" but the problem is that i just managed to put only the first image into every index using map and find
noticiasImages.forEach(function(data: { relationships: { field_imagen: {data: {id:any}}}} ) {
var nestedArray = noticiasData.map((noticiasImages: { id: any; }) => noticiasImages == noticiasData);
data = nestedArray && noticiasImages || noticiasData;
});
And this is my json (example node)
{
"data": [
"relationships": {
"field_imagen": {
"data": [
{
"type": "file--file",
"id": "dba917f0-b80f-45ed-a569-69f2ba2b482d",
}
],
}
]
},
this is the included object, who is in the same level as data
"included": [
"attributes": {
"drupal_internal__fid": 8798,
"langcode": "es",
"filename": "_DSC6472 - copia.jpg",
"uri": {
"value": "public:\/\/2019-11\/_DSC6472 - copia.jpg",
"url": "\/sites\/default\/files\/2019-11\/_DSC6472%20-%20copia.jpg"
},
},
,
Expected Result:
"data": [
"relationships": {
"type": "node--actualidad_institucional",
"id": "71514647-af49-4136-8a28-9563d133070a",
"field_imagen": {
"data": [
{
"type": "file--file",
"id": "dba917f0-b80f-45ed-a569-69f2ba2b482d",
"uri": {
"value": "public:\/\/2019-11\/_DSC6472 - copia.jpg",
"url": "\/sites\/default\/files\/2019-11\/_DSC6472%20-%20copia.jpg"
},
}
}
},
I put the uri from included into field_imagen. Tried to resolve like that, but it just put only the first image of the Array from the included object in every node:
showNoticias() {
this.frontService.getNoticias()
.subscribe((data: Noticias) => {
this.noticiasImages = Array.from(data.included);
this.noticiasData = Array.from(data.data);
let noticiasImages = this.noticiasImages.map((data: {id: any}) => data.id);
let noticiasData = this.noticiasData.map((data:{relationships: { field_imagen: { data: { id: any; }}}}) => data.relationships.field_imagen.data.id);
noticiasImages.forEach(function(data: { relationships: { field_imagen: {data: {id:any}}}} ) {
var nestedArray = noticiasData.map((noticiasImages: { id: any; }) => noticiasImages == noticiasData);
data = nestedArray && noticiasImages || noticiasData;
});
console.log(data);
});
}
Hope you can help me, thanks!
UPDATE: tried that but didnt work like expected
let merged = data.data.map((data:{relationships: { field_imagen: { data: any }}}) => Object.assign({}, noticiasImages));
console.log(data)
console.log(merged)
Sometimes using regular for loops are a better option. Using map with objects that have that many properties can get confusing. And using forEach will not give you access to the i index of the iteration in the loop, which makes things easier in this case.
for (let i = 0; i < obj.included.length; i++) {
let uri = obj.included[i].attributes.uri;
obj.data[i].relationships.field_imagen.data[0] = {
...obj.data[i].relationships.field_imagen.data[0],
...uri
}
}
console.log(obj)
Output:
{
"data": [
{
"relationships": {
"field_imagen": {
"data": [
{
"type": "file--file",
"id": "dba917f0-b80f-45ed-a569-69f2ba2b482d",
"value": "public://2019-11/_DSC6472 - copia.jpg",
"url": "/sites/default/files/2019-11/_DSC6472%20-%20copia.jpg"
}
]
}
}
}
],
"included": [
{
"attributes": {
"drupal_internal__fid": 8798,
"langcode": "es",
"filename": "_DSC6472 - copia.jpg",
"uri": {
"value": "public://2019-11/_DSC6472 - copia.jpg",
"url": "/sites/default/files/2019-11/_DSC6472%20-%20copia.jpg"
}
}
}
]
}

LogicApp/JavaScript - Split JSON data to multiple objects and arrays

I have below JSON data coming from source system into my Logic App:
[
{
"project":"abc",
"assignees":"123,456"
},
{
"project":"xyz",
"assignees":"123,468"
}
]
I want to split the "assignees", create arrays within objects, and produce below final output:
[
{
"metadata":{
"type":"project"
},
"name":"Project ABC",
"assignee":[
{
"metadata":{
"type":"assignment"
},
"employeeId":"123"
},
{
"metadata":{
"type":"assignment"
},
"employeeId":"123"
}
]
},
{
"metadata":{
"type":"project"
},
"name":"Project ABC",
"assignee":[
{
"metadata":{
"type":"assignment"
},
"employeeId":"123"
},
{
"metadata":{
"type":"assignment"
},
"employeeId":"468"
}
]
}
]
Can this be achieved in Logic App only? If not, can this be achieved using inline JavaScript code and how?
I don't know anything about LogicApp or how it works, but if all you want is javascript code that can make this transformation you can do something like this:
const src=[
{
"project":"abc",
"assignees":"123,456"
},
{
"project":"xyz",
"assignees":"123,468"
}
]
const transformed=src.map(entry=>({
"metadata":{type:"project"},
name:"Project "+entry.project.toUpperCase(),
assignee:entry.assignees.split(",").map(assignee=>({
metadata:{type:"assignment"},
emplyeeId:assignee
}))
}))
I initialize a variable named source to store same data source with yours.
And here provide a sample of inline javascript code for your reference:
var source = workflowContext.actions.Initialize_variable.inputs.variables[0].value;
var result = [];
source.forEach(sItem=>{
var resultItem = {
"metadata":{
"type":"project"
},
"name":"Project " + sItem.project.toUpperCase()
}
var assignee = [];
var assigneesSplit = sItem.assignees.split(",");
assigneesSplit.forEach(item=>{
var assigneItem = {
"metadata":{
"type":"assignment"
},
"employeeId":item
}
assignee.push(assigneItem);
});
resultItem.assignee = assignee;
result.push(resultItem);
});
return result;
After running the logic app, we can get the result data like:
[
{
"metadata": {
"type": "project"
},
"name": "Project ABC",
"assignee": [
{
"metadata": {
"type": "assignment"
},
"employeeId": "123"
},
{
"metadata": {
"type": "assignment"
},
"employeeId": "456"
}
]
},
{
"metadata": {
"type": "project"
},
"name": "Project XYZ",
"assignee": [
{
"metadata": {
"type": "assignment"
},
"employeeId": "123"
},
{
"metadata": {
"type": "assignment"
},
"employeeId": "468"
}
]
}
]
It seems there are some mistakes in your expected data sample(such as the second project name and the second employeeId in first assignee field). If they are not typo, please let me know, I will modify my js inline code to implement your expected json data.

change value of an array of nested objects to a string

this is the array that i currently have
const myArr = [
{
"code": {
"value": "AC16",
"description": "text"
},
"convictionDate": {
"value": "2019-03-07"
}
},
{
"code": {
"value": "AC20",
"description": "text"
},
"convictionDate": {
"value": "2019-03-06"
}
}
];
I want to map over each nested object inside the array so that the value of each nested object is the value property of that object as a string. so the object would become:
const myArr = [
{
"code": "AC16",
"convictionDate":"2019-03-07"
},
{
"code":"AC20",
"convictionDate": "2019-03-06"
}
]
Ive tried this with no success:
const x = myArr.map((item)=>{
console.log(item)
Object.keys(item).map(function(key,i) {
item[key] = item[key][value];
})
})
You are almost there. Just use array map
const myArr = [{
"code": {
"value": "AC16",
"description": "text"
},
"convictionDate": {
"value": "2019-03-07"
}
},
{
"code": {
"value": "AC20",
"description": "text"
},
"convictionDate": {
"value": "2019-03-06"
}
}
];
let newArray = myArr.map(function(item) {
return {
code: item.code.value,
convictionDate: item.convictionDate.value
}
});
console.log(newArray)
Map the array, and reduce the entries to the required object form:
const myArr = [{"code":{"value":"AC16","description":"text"},"convictionDate":{"value":"2019-03-07"}},{"code":{"value":"AC20","description":"text"},"convictionDate":{"value":"2019-03-06"}}];
const result = myArr.map(o =>
Object.entries(o).reduce((r, [k, { value }]) => ({ ...r, [k]: value }), {})
);
console.log(result);
const myArr = [
{
"code": {
"value": "AC16",
"description": "text"
},
"convictionDate": {
"value": "2019-03-07"
}
},
{
"code": {
"value": "AC20",
"description": "text"
},
"convictionDate": {
"value": "2019-03-06"
}
}
];
let newArray = myArr.map(e => {
return { "code":e.code.value, "convictionDate": e.convictionDate.value}
})
console.log(newArray);
It goes without saying there is some awesome reference material over at W3 Schools, the provide good detail on this in their article here
That said...
Why not simplify the code a little and try this against your array:-
const myArr = [
{
"code": {
"value": "AC16",
"description": "text"
},
"convictionDate": {
"value": "2019-03-07"
}
},
{
"code": {
"value": "AC20",
"description": "text"
},
"convictionDate": {
"value": "2019-03-06"
}
}
];
// PROPOSED SOLUTION CODE
const x = myArr.map((item)=>{
return {code: item.code.value,convictionDate: item.convictionDate.value}
});
// Your Desired Example Provided in Question
const xArr = [
{
"code": "AC16",
"convictionDate":"2019-03-07"
},
{
"code":"AC20",
"convictionDate": "2019-03-06"
}
];
// Output Validation
console.log('Response of Array \'x\'');
console.log(x);
console.log('Your Desired Example');
console.log(xArr);
When using 'map'; we must map the source array ('myArr') to our new target array ('x').
In the context of the example code you have provided, 'data.convictions' is undefined.
The magic is all here:-
const x = myArr.map((item)=>{
return {code: item.code.value,convictionDate: item.convictionDate.value}
});
Happy coding!

Lodash keyBy for multiple nested level arrays

I have an array of object, and i want to convert it into a map of key value pairs with the id as the key. However, I want to do it for both the root level and within the recipes attribute.
Array resp:
[
{
"id": "1",
"recipes": [
{
"id": 4036
},
{
"id": 4041
}
]
},
{
"id": "2",
"recipes": [
{
"id": 4052
},
{
"id": 4053
}
]
}
]
I came across _.keyBy() which maps an attribute as the key, but it doesn't allow nested levels.
Function:
var respObj = _.keyBy(resp, 'id');
Is there an elegant solution to massage resp to make all the objects nested within the array use id as key?
thanks!
you can do it with _.keyBy and _.mapValues
_.chain(resp)
.keyBy('id')
.mapValues(function(item) {
item.recipes = _.keyBy(item.recipes, 'id');
return item;
})
.value();
This is a generic solution that runs _.keyBy recursively on arrays, and the objects inside them:
function deepKeyBy(arr, key) {
return _(arr)
.map(function(o) { // map each object in the array
return _.mapValues(o, function(v) { // map the properties of the object
return _.isArray(v) ? deepKeyBy(v, key) : v; // if the property value is an array, run deepKeyBy() on it
});
})
.keyBy(key); // index the object by the key
}
I've added another level of data in the example (ingredients):
function deepKeyBy(arr, key) {
return _(arr)
.map(function(o) {
return _.mapValues(o, function(v) {
return _.isArray(v) ? deepKeyBy(v, key) : v;
});
})
.keyBy(key);
}
var arr = [{
"id": "1",
"recipes": [{
"id": 4036,
"ingerdients": [{
"id": 5555555
}, {
"id": 5555556
}, {
"id": 5555557
}]
}, {
"id": 4041
}]
}, {
"id": "2",
"recipes": [{
"id": 4052
}, {
"id": 4053
}]
}];
var result = deepKeyBy(arr, 'id');
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
You could get a flattened collection of recipes, concatenate the response and then key by id:
var result = _.chain(resp)
.flatMap('recipes')
.concat(resp)
.keyBy('id')
.value()
The flatMap call will pluck all the recipes from the response and flatten the arrays so we're left with this:
[
{ "id": 4036 },
{ "id": 4041 },
{ "id": 4052 },
{ "id": 4053 }
]
The response is then appended to this array using concat so we then have:
[
{ "id": 4036 },
{ "id": 4041 },
{ "id": 4052 },
{ "id": 4053 },
{ "id": "1", recipes: ... },
{ "id": "2", recipes: ... }
]
Finally we use keyBy to get the required structure .
var resp = [
{
"id": "1",
"recipes": [
{
"id": 4036
},
{
"id": 4041
}
]
},
{
"id": "2",
"recipes": [
{
"id": 4052
},
{
"id": 4053
}
]
}
]
var result = _.chain(resp)
.flatMap('recipes')
.concat(resp)
.keyBy('id')
.value()
document.getElementById('result').textContent = JSON.stringify(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
<p>
<pre id="result"></pre>
</p>

Categories