How can I Merge an array of objects - javascript

I was wondering how i could merge these two objects retrieve the tag values and store them in an array. This data is also coming from a json response so incoming data should be pushed onto the end of the new array.
so it would look something like this
["2011 LDI", "2012 LDI"]
array with incoming data:
["2011 LDI", "2012 LDI","2013 LDI"]
Here is what I am getting back in my console.log:
[19-08-25 21:58:32:055 PDT] []
[19-08-25 21:58:32:056 PDT] []
Here are the two objects of arrays i am trying to merge:
{date_added=2019-08-26 04:19:00.112083, tag=LDI 2011}
{date_added=2019-08-26 04:19:00.112089, tag=LDI 2012}
and I want it to look like this
[LDI 2011, LDI 2012]
and how I am trying to do it.
var tagtest = [];
var tags = message.student_detail.student_tags,
i = 0,
len = tags.length;
for (i; i < len; i++) {
var obj = tags[i];
for (a in obj) {
}
Array.prototype.push(tags, tagtest);
Logger.log(tagtest)
}

Based on your desired output ([LDI 2011, LDI 2012]), You may want the only tag values from the array, If this is what you are looking for then .map() will help you
const array = [
{
date_added: '2019-08-26',
tag: 'LDI 2011'
},
{
date_added: '2019-08-26',
tag: 'LDI 2012'
}];
const tags = array.map((r) => {
const chunk = r.tag.split(' ');
return `${chunk[1]} ${chunk[0]}`;
} );
console.log(tags);

A for in loop is a great way to work with objects. I updated the code above so that it was actually an array of objects, not an error. See below :)
var data = [{date_added: "2019-08-26 04:19:00.112083", tag: "LDI 2011"},
{date_added: "2019-08-26 04:19:00.112089", tag: "LDI 2012"}];
var newArr = [];
for(var item in data) {
newArr.push(data[item].tag);
}
console.log(newArr);

Related

How can I access to each field of a json object?

I have used csvtojson in order to write the csv data into a sql database, the object that the funcion return to have this structure:
var prueba = [
{'Aula;Capacidad': 'A10+11;112'},
{'Aula;Capacidad': 'A12;66' }
];
How can I acces to each field? I am trying to do console.log(prueba[0]["Capacidad"]) in order to see if it is running but it prints "undefined".
'Aula;Capacidad' is seen as a key, so you only can do the following:
console.log(prueba[0]["Aula;Capacidad])
which will write
A10+11;112
to the console.
Your properties are actually named 'Aula;Capacidad', meaning you'd need to use prueba[0]['Aula;Capacidad'] to get the value you are looking for.
This is what you need to iterate through the list of items:
var prueba = [{'Aula;Capacidad': 'A10+11;112'},{'Aula;Capacidad': 'A12;66' }];
for (var i = 0; i < prueba.length; i++) {
console.log(prueba[i]);
}
If you need to go deeper and iterate over every item properties:
var prueba = [{'Aula;Capacidad': 'A10+11;112'},{'Aula;Capacidad': 'A12;66' }];
for(var i = 0; i < prueba.length; i++) {
for(var p in prueba[0]) {
console.log(p, prueba[i][p]);
}
}
Your key you are looking up is in a composite key. So you would need to look it up with that composite key and than split it.
var prueba = [
{'Aula;Capacidad': 'A10+11;112'},
{'Aula;Capacidad': 'A12;66' }
];
console.log(prueba[0]['Aula;Capacidad'].split(";")[1]);
Other choice is to parse it all and look it up by the key.
var prueba = [
{'Aula;Capacidad': 'A10+11;112'},
{'Aula;Capacidad': 'A12;66' }
];
const parsed = prueba.reduce(function (arr, row) {
const entry = Object.entries(row)[0];
const keys = entry[0].split(";");
const values = entry[1].split(";");
const data = keys.reduce(function (o, key, index) {
o[key] = values[index];
return o;
}, {});
arr.push(data);
return arr;
}, []);
console.log(parsed[0].Capacidad);
console.log(parsed[1].Capacidad);
Your data looks malformed so you might need to do some manual processing.
You have an array of two items, both with a single key-value in them. You can do console.log(prueba[0]["Aula;Capacidad"]) and this will return 'A10+11;112'.
You might need to split things by the ; there so you could do something like this:
var prueba = [
{'Aula;Capacidad': 'A10+11;112'},
{'Aula;Capacidad': 'A12;66' }
];
prueba.forEach(item => {
const splitItem = item["Aula;Capacidad"].split(";");
console.log("Each item now looks like this: " + splitItem)
// You can access the first and second part of the item like this
console.log(splitItem[0], splitItem[1])
})
To be honest, I'd go back and look at how this data is being added to your DB. It looks messed up.

How to create a new array from multiple arrays

I'm trying to somewhat combine 3 arrays to create a new one. So the end result is
<li>array1[0]array2[0]array3[0]</li>
I tried a for loop but it ends up with 27 answers and there should only be 2 with the data I have.
// const ingredientsList = () => {
// for (let i = 0; i < recipe.ingredients.length; i++) {
// for (let j = 0; j < recipe.size.length; j++) {
// for (let k = 0; k < recipe.amount.length; k++) {
// console.log(recipe.amount[k], recipe.size[j], recipe.ingredients[i]);
// <li>
// {recipe.amount[k]}
// {recipe.size[j]}
// {recipe.ingredients[i]}
// </li>;
// }
// }
// }
// };
I would greatly appreciate anyone's help. I'm currently working in reactjs. Each array is the same length. I have 3 arrays: ingredient list, amount, and size. So I want to combine them so they read smoothly such as "1 cup flour"
The way you are looping through the three arrays will end up as such (in pseudo code):
Loop through the first array and for every element:
Loop through the second array and for every element:
Loop through the third array and
for every element create a list item of each element at index n from
each array.
Since I am not sure exactly what you are wanting I will have to assume they are the same length arrays so you can do:
for(let i = 0; i < recipe.amount.length; i++) {
console.log(`${recipe.amount[i]} ${recipe.size[i]} ${recipe.ingeredients[i]}`)
}
This should get you logging the appropriate results, then just create the html list elements.
If I understand correctly based on the code in the question, you have three arrays (ingredients, size, amount).
If each of the arrays is the same length and each index's data corresponds to the data at the same index of the others, you could write a loop using the length of one of them and pass the same index into each array like...
for (let i = 0; i < recipe.ingredients.length; i++) {
console.log(
recipe.ingredients[i],
recipe.size[i],
recipe.amount[i],
);
}
Seeing as you're working in react though, if you have control over the data yourself, it would probably make more sense to store each instruction in an object in a recipe array, then map over that array and create the list item like...
Somewhere in the component could be something like...
this.recipe = [
{
ingredient: 'something',
amount: 'some amount',
size: 'some size',
},
{
ingredient: 'something',
amount: 'some amount',
size: 'some size',
},{
ingredient: 'something',
amount: 'some amount',
size: 'some size',
}
]
and in the template...
{
recipe.map((instruction) => (
<li>
{ instruction.amount }
{ instruction.size }
{ instruction.ingredient }
</li>
));
}
const emp1 = ["Cecilie", "Lone"];
const emp2 = ["Emil", "Tobias", "Linus"];
const allEmp = emp1.concat(emp2);
you can try using concat keyword to merge arrays. In case of more than two arrays you can use
emp3 = ["john", "lacy"]
const allEmp = emp1.concat(emp2, emp3);

Find data from the strings of array2 in the array1 and save as new uniq array

I want to find strings that has data from the strings from the array 2 in the array1 and save result as separate uniq array.
As can you see I search for not exact values. From the array1 values I know only part of the information, and I want to find the complete strings, with that information, in array1. And at the end I want to save what I found. So, I don't have a problem with finding here, but a problem with saving in the valid single JSON.
Array examples:
Array #1:
{
"overflow": [
"id:address:name:location:email",
...
"id2:address2:name2:location2:email2"
]
}
Array #2:
[
"location:email",
...
"location2:email2"
]
Code:
resultArr: function() {
var arr1 = '/var/log/1.json';
var arr2 = '/var/log/2.json';
var arrResult = '/var/log/result.json';
var arr2Obj = JSON.parse(fs.readFileSync(arr2, 'utf-8'));
for (var i = 0; i < arr2Obj.length; i++) {
var arr1Obj = JSON.parse(fs.readFileSync(arr1, 'utf-8'));
arr1Obj.overflow = arr1Obj.overflow.filter(function(e) {
return e.includes(arr2Obj[i])
});
fs.appendFile(arrResult, JSON.stringify(arr1Obj, null, 2), 'utf-8');
}
}
My result:
[{
"overflow": [
"id:address:name:location:email"
]
}{
"overflow": [
"id54:address54:name54:location54:email56"
]
}{
"overflow": [
"id2:address2:name2:location2:email2",
"id6:address6:name6:location2:email2"
]
}
What I really want:
{
"overflow": [
"id:address:name:location:email",
"id54:address54:name54:location54:email56",
"id6:address6:name6:location2:email2",
"id2:address2:name2:location2:email2"
]
}
Instead of reading the file again and again, and appending to the result repeatedly, just do both actions only once. All the rest should happen in memory.
You will also get better results (no risk for duplicates in result) when you swap the loops: put the filter action as the outer loop. For the inner loop you can use some, since one match is enough for the entry to be included:
resultArr: function() {
var arr1 = '/var/log/1.json',
arr2 = '/var/log/2.json',
arrResult = '/var/log/result.json',
arr2Obj = JSON.parse(fs.readFileSync(arr2, 'utf-8')),
arr1Obj = JSON.parse(fs.readFileSync(arr1, 'utf-8'));
arr1Obj.overflow = arr1Obj.overflow.filter(function(e) {
return arr2Obj.some(function (f) {
return e.includes(f)
});
});
fs.writeFileSync(arrResult, JSON.stringify(arr1Obj, null, 2), 'utf-8');
}
At each iteration, you're creating a new object and appening it to a file.
JSON is not a good format to append to.
You're replacing the array instead of adding fields to it.
You can do it that way, it should work :
resultArr: () => {
let arr1 = '/var/log/1.json';
let arr2 = '/var/log/2.json';
let arrResult = '/var/log/result.json';
let arr2Obj = JSON.parse(fs.readFileSync(arr2, 'utf-8'));
let arr1Obj = JSON.parse(fs.readFileSync(arr1, 'utf-8')); // reading only one time
arr1Obj.overflow = arr2Obj.map(value => {
return arr1Obj.overflow.filter(e => return e.includes(value))
});
fs.writeFileSync(arrResult, JSON.stringify(arr1Obj, null, 2), 'utf-8'); //Writing only one time
}
Array.map() executes the closure for each field in your array and group all the values returned by the closure in another array.
I also replaced some keywords to make your code more ES6 compliant. I you really want to append, you should use CSV and not JSON.

Javascript Array of Objects and Unique Values

I have an array of objects that looks like this:
[
{"name":"Andrea","from":"USA","Food":"Candy"},
{"name":"Matt","from":"Taiwan","Food":"Chicken"},
{"name":"Roddy","from":"USA","Food":"Rice"},
{"name":"Andy","from":"Great Britain","Food":"Steak"},
];
Is there a way to get the list of all countries from the array above, and get rid of the repeated ones?
So from the list above, the list I am to obtain is:
["USA", "Taiwan", "Great Britain"]
Thank you!
Just loop over people and insert unique countries in a new array. Here is an example.
var countries = [];
var people = [
{"name":"Andrea","from":"USA","Food":"Candy"},
{"name":"Matt","from":"Taiwan","Food":"Chicken"},
{"name":"Roddy","from":"USA","Food":"Rice"},
{"name":"Andy","from":"Great Britain","Food":"Steak"},
];
for (var i = 0, l=people.length; i < l; i++) {
if(people[i] && people[i].from) {//ensure country exists
if (countries.indexOf(people[i].from) == -1) {//ensure unique
countries.push(people[i].from);
}
}
}
Yet another variant with reduce
var arr = [
{"name":"Andrea","from":"USA","Food":"Candy"},
{"name":"Matt","from":"Taiwan","Food":"Chicken"},
{"name":"Roddy","from":"USA","Food":"Rice"},
{"name":"Andy","from":"Great Britain","Food":"Steak"},
];
var countries = arr.reduce(function(acc, cur){
if(!acc.map[cur.from]){
acc.map[cur.from]=true;
acc.result.push(cur.from);
}
return acc;
}, {result:[], map:{}}).result;
var arr = [
{"name":"Andrea","from":"USA","Food":"Candy"},
{"name":"Matt","from":"Taiwan","Food":"Chicken"},
{"name":"Roddy","from":"USA","Food":"Rice"},
{"name":"Andy","from":"Great Britain","Food":"Steak"},
];
var countries = arr.reduce(function(acc, cur){
if(!acc.map[cur.from]){
acc.map[cur.from]=true;
acc.result.push(cur.from);
}
return acc;
}, {result:[], map:{}}).result;
document.getElementById('countries').innerHTML = countries.join();
<span id="countries"></span>
If you are already using the excellent Lodash library, the following will do it for you neatly in one line:
var uniqueCountries = _(dataArray).pluck('from').unique().value();
UnderscoreJS has similar functionality using chaining.
For D3.js, the following will do it:
var uniqueCountries = d3.set(dataArray.map(function (x) { return x.from; })).values();
Without doing the unique-ifying on the server and returning that data separately, there is no way to get around looping through all records at least once to do this. For 1000 records or so, though, this will still be very fast.
For plain JS, see other answers.
I'd loop over the Array and put the country into an array if it is not yet inside that array.

Best way to store this data (array, object, etc)

I need to store (many) objects or arrays of data, which need to have the following criteria:
I need to be able to add a new set of data into the existing data easily
I need to be able to sort the data by date/ time added easily (array in order of when entries were pushed to it)
I need to be able to grab an entry easily using a reference, either integer or string. This is important, at the moment I have to do an $.each() to loop through my data until I find the entry I want.
I have tried using a structure like:
saved_info = {
1001: {//all my data for ref 1001},
1002: {//all my data for ref 1002}
}
which gave me what wanted of being able to grab the info easily given a reference:
info = saved_info[1001];
however, the reference numbers I use aren't in order - I use a reference given to me (its a unique identifier), therefore the object isn't in order of when items were added/saved/pushed.
You can use two objects:
One that stores the data by key
Another that stores the sort order
This way you can (i) lookup an element by key (ii) loop over elements in the order they were inserted. Rough outline of the structure:
var DataObject = {
data: {},
sort: []
};
Here is how you add data to this structure:
DataObject.data[1004] = {name: "Test 4"};
DataObject.sort.push(1004);
DataObject.data[1001] = {name: "Test 1"};
DataObject.sort.push(1001);
DataObject.data[1003] = {name: "Test 3"};
DataObject.sort.push(1003);
DataObject.data[1002] = {name: "Test 2"};
DataObject.sort.push(1002);
Here is how you perform a random access:
console.log(DataObject.data[1001].name);
console.log(DataObject.data[1003].name);
And here is how you iterate over all elements in the order they were added:
var i;
for (i = 0; i < DataObject.sort.length; i++) {
console.log(DataObject.data[DataObject.sort[i]].name);
}
It is possible to wrap the entire logic inside a class:
function DataObject() {
this.data = {};
this.sort = [];
this.setItem = function (k, v) {
this.data[k] = v;
this.sort.push(k);
};
this.getItemByKey = function (k) {
return this.data[k];
};
this.getItemByPos = function (i) {
return this.data[this.sort[i]];
};
this.getAllItems = function () {
var i, r = [];
for (i = 0; i < this.sort.length; i++) {
r.push(this.data[this.sort[i]]);
}
return r;
};
}
var t = new DataObject();
t.setItem(1001, {name: "Test 1"});
t.setItem(1002, {name: "Test 2"});
t.setItem(1003, {name: "Test 3"});
t.setItem(1004, {name: "Test 4"});
console.log(t.getItemByKey(1001));
console.log(t.getItemByPos(0));
console.log(t.getAllItems());
Try to build a Json like this,
var xJson = {
"1001":{//all my data for ref 1001},
"1002":{//all my data for ref 1002}
};
and you can fetch the records as per your wish using the bracket notation, since we are using a numeric value as a key.
var xData = xJson["1001"];

Categories