Javascript push array item to named index - javascript

I have a JSON array:
[{ id: 1, client: "Microsoft" },{ id: 2, client: "Microsoft"
},{ id: 3, client: "Apple" }]
and I'd like to group it by "client", but I'm having difficulty with this in javascript. In PHP i'd typically do something like this:
$group = array();
foreach ($array as $item) {
$group[ $item['client'] ] = $item;
}
return $group;
But this method totally wont't work in javascript on a multidimensional array
var group = [];
for ( i=0 ... ) {
var client = array[i].client;
group[ client ].push( array[i] );
}
How would I go about grouping the above array into something like this:
[{ "Microsoft": [{...}], "Apple":[{...}] }]
or even
[{ client: "Microsoft", "items": [{...}] }, { client: "Apple", items: [{...}] }]

You need an object for that, not an array:
var array = [{ id: 1, client: "Microsoft" },{ id: 2, client: "Microsoft" },{ id: 3, client: "Apple" }];
var group = {};
for (var i=0; i<array.length; i++) {
var client = array[i].client;
group[client] = group[client] || []; // create array for client if needed
group[client].push(array[i]);
}
console.log(group);
It's important to keep in mind that the resulting object will contain references to the objects from the original array. For example:
array[0].id = 100;
group.Microsoft[0].id; // 100

Related

I want to change the structure of my array

I need to modify a data which is coming from API. The data is coming in the form of array of objects.
const crosses = [
{
fatherLineId: 8,
fatherLineName: "2ART18-0008",
id: 54,
motherLineId: 5,
motherLineName: "2ART18-0005",
},
{
fatherLineId: 3
fatherLineName: "2ART18-0003",
id: 55,
motherLineId: 5,
motherLineName: "2ART18-0005",
}
]
I want my data to be restructured in the form of:
const resultantArr = [
{
enteryNumber: 1,
ParentName: "2ART18-0008"
},
{
entryNumber: 2,
ParentName: "2ART18-0005",
},
{
entryNumber: 3,
ParentName: "2ART18-0003"
},
and so on ...
];
Here the parentName property will have motherLineName values and fatherLineName values in the order.
When you get the result of the api call, loop through it and map the data toy our custom object, I can't provide a complete example based on your question but something like this:
You may also need to parse the apiresult into json using JSON.parse()
var resultantArr = [];
for(var i = 0; i < apiresult.length; i++)
{
resultantArr.push({"enteryNumber" : i + 1 , "ParentName" : apiresult[i].fatherLineName });
}
Loop over the array and push two separate objects into an output array. And keep a record of each object entryname that you increment by two at the end of each iteration.
const crosses=[{fatherLineId:8,fatherLineName:"2ART18-0008",id:54,motherLineId:5,motherLineName:"2ART18-0005"},{fatherLineId:3,fatherLineName:"2ART18-0003",id:55,motherLineId:5,motherLineName:"2ART18-0005"}];
const out = [];
let count = 1;
crosses.forEach(obj => {
const { fatherLineName, motherLineName } = obj;
out.push({
entryNumber: count,
parentName: fatherLineName
});
out.push({
entryNumber: count + 1,
parentName: motherLineName
});
count = count + 2;
});
console.log(out);
Hope it helps you... 🙂
const crosses = [
{
fatherLineId: 8,
fatherLineName: "2ART18-0008",
id: 54,
motherLineId: 5,
motherLineName: "2ART18-0005",
},
{
fatherLineId: 3,
fatherLineName: "2ART18-0003",
id: 55,
motherLineId: 5,
motherLineName: "2ART18-0005",
}
];
var result = [];
var count = 1;
crosses.forEach(cross => {
result.push({
parentName: cross.fatherLineName,
entryNumber: count++,
}),
result.push({ parentName: cross.motherLineName,
entryNumber: count++,
})
});
result

Creating entites in Dialogflow using Node.js

I'm trying to create entites in Dialogflow using node.js. The entity values will come from a JSON file. I'm currently testing it using postman. However, the entity values are not being separated and being combined in only one line. How do I fix this? Thank you
This is my sample JSON file that is being sent.
{
"Entity_Values": [
{
"Value": "One",
"Synonym":["Solo","1"]},
{
"Value": "Two",
"Synonym":["Double","2"]}
],
"Entity_Name": "Sample"}
This is what I have so far:
function createEntity (inputEntityobj, EntityName) {
const promises = [];
let entity_values = {value:[], synonyms:[]};
let inputEntity_values = [inputEntityobj];
for (i = 0; i < inputEntityobj.length; ++i) {
let inputEntity_values = [inputEntityobj[i].Value];
let inputEntity_synonym = [inputEntityobj[i].Synonym];
entity_values.value.push(inputEntity_values);
entity_values.synonyms.push(inputEntity_synonym);
}
const sizeRequest = {
parent: agentPath,
entityType: {
displayName: (EntityName),
kind: 'KIND_MAP',
autoExpansionMode: 'AUTO_EXPANSION_MODE_UNSPECIFIED',
enableFuzzyExtraction: true,
entities: [entity_values],
},
};
This code outputs
value: [ [ 'One' ], [ 'Two' ] ], synonyms: [ [ [Array] ], [ [Array] ] ]
And in Dialogflow, these are all in one entity entry instead of being in two separate entries.
Your JSON input is almost identical to the required object format for entities (reference) and will only need a little bit of tweaking to make it work. Using your JSON, I renamed the Value and Synonym to value and synonyms. Loop through Entity_values and push the key value pair to list entityVal and use it for the request.
'use strict';
const dialogflow = require('#google-cloud/dialogflow').v2;
var inputEntityObj = {
"Entity_Values": [
{
"Value": "One",
"Synonym":["Solo","1"]},
{
"Value": "Two",
"Synonym":["Double","2"]}
],
"Entity_Name": "Sample"};
var obj = inputEntityObj['Entity_Values'];
// rename keys
var res = obj.map(item => {
item.value= item.Value;
item.synonyms= item.Synonym;
delete item.Value;
delete item.Synonym;
return item;
});
var entityVal =[];
for (const entity in res){
entityVal.push(res[entity]);
}
var projectId = 'your-project-id';
var entityType = { displayName: 'test', //hard coded value for testing purposes
kind: 'KIND_MAP',
autoExpansionMode: 'AUTO_EXPANSION_MODE_UNSPECIFIED',
enableFuzzyExtraction: true,
entities: entityVal,
};
var parent = `projects/${projectId}/agent`;
var request = { parent: parent,
entityType: entityType
};
console.log(JSON.stringify(request, null, 2));
const client = new dialogflow.EntityTypesClient();
client.createEntityType(request);
See testing done below:
request structure:
{
"parent": "projects/your-project-id/agent",
"entityType": {
"displayName": "test",
"kind": "KIND_MAP",
"autoExpansionMode": "AUTO_EXPANSION_MODE_UNSPECIFIED",
"enableFuzzyExtraction": true,
"entities": [
{
"value": "One",
"synonyms": [
"Solo",
"1"
]
},
{
"value": "Two",
"synonyms": [
"Double",
"2"
]
}
]
}
}
Created entity in dialogflow:

Issue while converting array from one format to another

I have the following input array(It's a Javascript Object[] Array response):
[
{index:1, headerCSV:"Name", dataFields: ["Name", "Id"]},
{index:2, headerCSV:"Id", dataFields: ["Test", "Test 1"]},
{index:3, headerCSV:"fname", dataFields: ["Test", "Test 1"]},
{index:4, headerCSV:"lname", dataFields: []},
]
I am trying to convert it to the following array:
[
{"header" : 1, "field" :"Name"},
{"header" : 1, "field" :"Id"},
{"header" : 2, "field" :"Test"},
{"header" : 2, "field" :"Test 1"},
{"header" : 3, "field" :"Test"},
{"header" : 3, "field" :"Test 1"}
]
In the result array I'll need to put in the header with the input array index and in the field I'll need to construct using the array of the dataFields array of the input array. I have tried with the following code:
var CSVHeadersAndFields = /* The input array */;
var headerFieldMappingJSON = [];
for(var i=0; i<CSVHeadersAndFields.length;i++) {
headerFieldMappingJSON[i] = {};
var selectedFields = CSVHeadersAndFields[i].dataFields;
for(var j=0; j<selectedFields.length;j++) {
headerFieldMappingJSON[i].header = CSVHeadersAndFields[i].index;
headerFieldMappingJSON[i].field = selectedFields[j];
}
}
But I have got the following result:
[
{"header":1,"field":"Name"},
{"header":2,"field":"Test"},
{"header":3,"field":"Test"},
{}
]
I suspect form the for loop 1st iteration value is replaced by the second iteration and also I'll need to avoid to construct the output array mapping from the empty array of dataFields from the input array.
How to make a correct algorithm to convert the array?
Make a separate iterator index for the result array. Or just push to the result array instead of adding values by index:
var CSVHeadersAndFields = /* The array from question */;
var headerFieldMappingJSON = [];
for(var i = 0; i < CSVHeadersAndFields.length; i++) {
var selectedFields = CSVHeadersAndFields[i].dataFields;
for(var j = 0; j < selectedFields.length; j++) {
headerFieldMappingJSON.push({
header: CSVHeadersAndFields[i].index,
field: selectedFields[j]
});
}
}
The same example but cleaner:
var input = /* The array from question */;
var output = [];
input.forEach(function (csvRow) {
csvRow.dataFields.forEach(function (field) {
output.push({
header: csvRow.index,
field: field
});
});
});
You can try following approach:
Logic:
Loop over data and push data in an array based on parsing logic.
In every iteration, you can again loop over obj.dataFields and create object for every field.
You can then merge this output array to original output list.
var data = [
{index:1, headerCSV:"Name", dataFields: ["Name", "Id"] },
{index:2, headerCSV:"Id", dataFields: ["Test", "Test 1"] },
{index:3, headerCSV:"fname", dataFields: ["Test", "Test 1"] },
{index:4, headerCSV:"lname", dataFields: []}
];
var output = data.reduce((acc, obj) => {
const header = obj.index;
return acc.concat( obj.dataFields.map((field) => ({ header, field}) ))
}, []);
console.log(output)
The code below will give you one result object per dataField and use the index property from CSVHeadersAndFields as the header property for each of them.
const result = CSVHeadersAndFields.map(item =>
item.dataFields.map(field => {
return {
header: item.index,
field
}
})
);
here is the simpler code:
var CSVHeadersAndFields = [ {index:1, headerCSV:"Name", dataFields: ["Name","Id"]},
{index:2, headerCSV:"Id", dataFields:["Test","Test 1"]},{index:3, headerCSV:"fname", dataFields:["Test","Test 1"]}, {index:4, headerCSV:"lname", dataFields:[]};
var headerFieldMappingJSON = [];
for(var CSVHeadersAndField of CSVHeadersAndFields ) {
for(var dataFieldVal of CSVHeadersAndField['dataFields']){
headerFieldMappingJSON.push({'header': CSVHeadersAndField['index'], 'field': dataFieldVal })
}
}
output:
[
{
"header": 1,
"field": "Name"
},
{
"header": 1,
"field": "Id"
},
{
"header": 2,
"field": "Test"
},
{
"header": 2,
"field": "Test 1"
},
{
"header": 3,
"field": "Test"
},
{
"header": 3,
"field": "Test 1"
}
]

How to form nested objects in Javascript

I am trying to dynamically form a nested tree object something like below using JavaScript, can someone please let me know the best way to achieve this?
var contextpath= {
text: "TreeRoot",
items: [ {
text: "subgroup1" ,
items: [ {
text: "subgroup2",
items: [ {
text: "subgroup3",
items: [ {
text: "subgroup4",
items: [ {
text: "subgroup5"
}]
}]
}]
}]
}]
};
I have delimited string that I am trying to convert to object (that can be used as dat source for tree component).
var path="TreeRoot|subgroup1|subgroup2";
Trying to implement something like below but with recursion / looping using less number of variables.
var contextpathText= {};
contextpathText.text ="TreeRoot";
var childObject={};
var items=[];
childObject.text ="subgroup1";
items.push(childObject);
contextpathText.items=(items);
You need a depth counter and to store the current levels of the object you're working with.
var obj = {text:''}, parent, child, i = 0;
obj.text = 'TreeRoot';
parent = obj;
while (++i <= 5) {
if (parent.items === undefined) parent.items = []; // because you don't have an items on the last subgroup you can't put it in the object literal
child = {text: 'subgroup'+i};
parent.items.push(child);
parent = child;
}
parent = child = null; // cleanup
obj;
jsbeautified JSON.stringify(obj) is now
{
"text": "TreeRoot",
"items": [{
"text": "subgroup1",
"items": [{
"text": "subgroup2",
"items": [{
"text": "subgroup3",
"items": [{
"text": "subgroup4",
"items": [{
"text": "subgroup5"
}]
}]
}]
}]
}]
}
Edit For delimited string
var path = 'TreeRoot|subgroup1|subgroup2';
var obj = {text:''}, parent, child, levelText = path.split('|').reverse();
obj.text = levelText.pop() || '';
parent = obj;
while (levelText.length > 0) {
child = {text: levelText.pop()};
if (!parent.items) parent.items = [];
parent.items.push(child);
parent = child;
}
obj;
Beat me to it, but I went with this code:
var contextpath = { text: "TreeRoot", items: []}
var items = contextpath.items;
for(var i = 1; i <= 5; i++) {
items.push({ text: "subgroup" + i, items: []});
items = items[0].items;
}
The parent & child nomenclature is definitely clearer, for this sort of thing, but I wanted to show that you didn't have to declare the new object as a variable first, you can just push the object literal.
Whoops, just now noticed that you don't have an items array in your desired structure. My code creates the spare, so you end up with
// snip
text: "subgroup4",
items: [ {
text: "subgroup5",
items: []
}]
// etc.

json array: How to create new array elements?

My aim is to get a json array like this one:
var args = [{ name: 'test', value: 1 }, { key: 'test2', value: 2}];
How can I get the below code to build up an array like the above one?
this.dependentProperties = []; //array
function addDependentProperty(depName, depValue) {
dependentProperties.push(new Array(depName, depValue));
}
By using the push method I end up having a json notation like this one:
args:{[["test1",1],["test2",2]]}
dependentProperties.push({name: depName, value: depValue});
var args = [{ name: 'test', value: 1 }, { key: 'test2', value: 2}];
...this is an array where each element is a associated-array (=hash, =object).
dependentProperties.push(new Array(depName, depValue));
...you are pushing a (sub-)Array into the parent array. That's not the same as an associative array. You now have a heterogeneous array.
dependentProperties.push({name: depName, value: depValue});
...This is pushing an associated-array into your top-level array. This is what you want. Luca is correct.
newObject = {
"first": "John",
"last": "Doe",
"age": 39,
"sex": "M",
"salary": 70000,
"registered": true,
"interests": [ "Reading", "Mountain Biking", "Hacking" ]
}
var myarray = [];
var myJSON = "";
for (var i = 0; i < 10; i++) {
var item = {
"value": i,
"label": i
};
myarray.push(item);
}
myJSON = JSON.stringify({myarray: myarray});

Categories