Angularjs: Convert objects to arrays - javascript

This is my data:
$scope.data = [
{
"top":"2",
"status":"1",
"name":"Anna",
},
{
"top":"2",
"status":"1",
"name":"Jodie",
},
{
"top":"2",
"status":"1",
"name":"susan",
}
];
Now I want to convert the objects to arrays. When I run my program I get this following output in console log:
{
"1":{
"2":"3"
}
}
But I need them to output as an array not object. Someone told me to use map function but I need to do them without using map function because it will cause a conflict in the process of my project. Is there any other way to do it without using map function?
The 1 in output means status object. 2 means top object and 3 means the number of students who's top is in 2.
This is the code I have so far: http://jsfiddle.net/DharkRoses/sjz5aLv1/
Any suggestions? TIA
Update:
I want the output which looks like this:
(
[1] =>Array
(
[2] => 3
)
)

I took below array for processing:
$scope.data = [
{ "top": "1", "status": "1", "name": "Anna" },
{ "top": "2", "status": "1", "name": "Jodie" },
{ "top": "2", "status": "1", "name": "Susan" },
{ "top": "3", "status": "1", "name": "Eddie" },
{ "top": "2", "status": "2", "name": "Megan" },
{ "top": "2", "status": "2", "name": "Frank" }
];
If I am not wrong you want a response like that:
[
{
"1": [
{ "1": 1 },
{ "2": 2 },
{ "3": 1 }
]
},
{
"2": [
{ "2": 2 }
]
}
]
This is a live demo in order to achieve above result: http://jsfiddle.net/nerezo/vz0dbdeq/

Related

How can I .filter an object by elements within an array inside an object?

I've been playing around trying to learn in an API project using Postman and conducting tests using JavaScript. So far, I have succeeded with the help of reading on websites and watching YouTube videos. Of course, previous tests and playing around have been fairly easy but now I came to a stop. I really tried to figure this out for several weeks but I need further guidance, a push in the right direction or direct help.
What I'm trying to do is to filter out some of the response to only view objects that contain specific data.
To do that, I'm using a filter where I want all products containing a specific value inside an array "product_option_values".
My first approach was to see if I could sort products having any values from the first array, and it worked. It filters just fine.
var filterSmall = jsonData.products.filter(fs => fs.associations.product_option_values);
My next approach was to get to my goal of filtering out products according to specific values inside this array. I tried many simple .(dot) combinations and pointing to [index] to access it without any luck. (I must add that I know how to access this from a specific product, but that way doesn't work when filtering).
I've also tried other approaches such as:
var filterSmall = jsonData.products.filter(fs => fs.associations["product_option_values", 0, "name"] === "S");
and other similar combinations.
This is a very shortened sample of the structure of "products" which in its full form consists of 20 products and far more values inside of it:
{
"products": [
{
"id": 16,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Mountain fox notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "22"
},
{
"id": "23"
}
]
}
},
{
"id": 17,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Brown bear notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "23"
},
{
"id": "24"
}
]
}
}
]
}
and here is a small and expanded sample from product_option_values:
{
"product_option_values": [
{
"id": 1,
"id_attribute_group": "1",
"color": "",
"position": "0",
"name": "S"
},
{
"id": 2,
"id_attribute_group": "1",
"color": "",
"position": "1",
"name": "M"
},
{
"id": 3,
"id_attribute_group": "1",
"color": "",
"position": "2",
"name": "L"
}
]
}
How do I proceed? Did I do anything correct or even close to it?
Perhaps I've been staring at this for too long.
Thanks in advance.
If you want to compare nested attributes you have to transform the objects (e.g. by using a map operation), so that the relevant attributes are easily accessible for a comparison. If you want to filter by product_option_value id, you could do something like this:
const jsonData = {
"products": [
{
"id": 16,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Mountain fox notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "22"
},
{
"id": "23"
}
]
}
},
{
"id": 17,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Brown bear notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "23"
},
{
"id": "24"
}
]
}
}
]
};
const sample = {
"product_option_values": [
{
"id": 22,
"id_attribute_group": "1",
"color": "",
"position": "0",
"name": "S"
},
{
"id": 2,
"id_attribute_group": "1",
"color": "",
"position": "1",
"name": "M"
},
{
"id": 3,
"id_attribute_group": "1",
"color": "",
"position": "2",
"name": "L"
}
]
};
const ids = sample.product_option_values.map((el) => String(el.id));
console.log(ids);
const filtered = jsonData.products.filter((fs) => fs.associations.product_option_values.map((e) => e.id).some((f) => ids.includes(f)));
console.log(filtered);

Replacing Data in Array

I am working on an angular application. I have an array as follows:
[{
"Name": "Andy"
},
{
"Name": "Bayer"
},
{
"Name": "James"
},
{
"Name": "Doda"
}]
I have another array which containes data as follows:
[
{
"Name": "Andy",
"Id": "1",
"Time": "2020-06-19T11:02+00:00"
},
{
"Name": "Billy",
"Id": "2",
"Time": "2020-06-19T11:05+00:00"
},
{
"Name": "Ciena",
"Id": 5
"Time": "2020-06-19T11:05+00:00"
},
{
"Name": "Doda",
"Id": "4",
"Time": "2020-06-19T11:05+00:00"
}
]
I want a resultant array such that code should check if Name is present in first array, then it should copy data from second array for that Name and push it in resultant array. For example common name between above two array is Andy and Doda, so data from Andy and Doda should be pushed to resultant array as follows:
[{
"Name": "Andy",
"Id": "1",
"Time": "2020-06-19T11:02+00:00"
},
{
"Name": "Bayer"
},
{
"Name": "James"
},
{
"Name": "Doda",
"Id": "4",
"Time": "2020-06-19T11:05+00:00"
}]
At run time I may get many names so code should be generic. I was trying following code which I got over stackoverflow itself
this.newArray = _.map(this.resultantArray, item => {
const value = _.find(this.dataArray, ['Name', item]);
const obj = value ? value : {Name: item};
return obj;
});
But this code is not working as expected as it works fine for the first time but when data comes for second time it appends data to previous data. I want array to be populated again freshly every time I send data. Please help
You can do this with vanilla JS no need for lodash. You can first map it and inside that you can find the value from second array otherwise return the current object:
var arrayTwo = [ { "Name": "Andy", "Id": "1", "Time": "2020-06-19T11:02+00:00" }, { "Name": "Billy", "Id": "2", "Time": "2020-06-19T11:05+00:00" }, { "Name": "Ciena", "Id": "5", "Time": "2020-06-19T11:05+00:00" }, { "Name": "Doda", "Id": "4", "Time": "2020-06-19T11:05+00:00" } ];
var arrayOne = [{ "Name": "Andy"}, { "Name": "Bayer"}, { "Name": "James"}, { "Name": "Doda"}];
var result = arrayOne.map(val=>arrayTwo.find(p=>p.Name==val.Name) || val);
console.log(result);
Suppose first array name is First
First : any [] = [{"Name": "Andy"},{"Name": "Bayer"},{ "Name": "James"},{"Name": "Doda"}]
And Second array name is Second
Second : any[] = [{"Name": "Andy","Id": "1","Time": "2020-06-19T11:02+00:00"},{"Name": "Bayer"},{"Name": "James"},{"Name": "Doda","Id": "4","Time": "2020-06-19T11:05+00:00"}]
Now do looping and check each name of first if its exists in second copy from second and push in result array
result : any[] =[];
this.First.forEach((element) => {
let index = this.Second.findIndex((x) => element.Name== x.Name);
if (index > -1) {
let data = {
this.Second[index].Name,
this.Second[index].Id,
this.Second[index].time,
};
this.result.push(data);
}
}

Most performant way to sort a deeply nested array of objects by another deeply nested array of objects

As an example - I've included a one element array that contains an object that has a Children key, which is an array of objects and each object also has its' own Children key that contains another array.
[
{
"Id": "1",
"Children": [
{
"Id": "2",
"Children": [
{
"Id": "10",
"DisplayName": "3-4",
},
{
"Id": "1000",
"DisplayName": "5-6",
},
{
"Id": "100",
"DisplayName": "1-2",
},
]
}
]
}
]
There is a second array of objects that I would like to compare the first array of objects to, with the intention of making sure that the first array is in the same order as the second array of objects, and if it is not - then sort until it is.
Here is the second array:
[
{
"Id": "1",
"Children": [
{
"Id": "2",
"Children": [
{
"Id": "100",
"DisplayName": "1-2",
},
{
"Id": "10",
"DisplayName": "3-4",
},
{
"Id": "1000",
"DisplayName": "5-6",
},
]
}
]
}
]
The data that this will run on can be up in the tens of thousands - so performance is paramount.
What I'm currently attempting is using a utility method to convert each element of the second array into a keyed object of objects e.g.
{
1: {
"Id": "1",
"Children": [
{
"Id": "2",
"Children": [
{
"Id": "4",
"DisplayName": "3-4",
},
{
"Id": "3",
"DisplayName": "1-2",
},
]
}
]
}
}
This allows fast look up from the top level. I'm wondering if I should continue doing this all the way down or if there is an idiomatic way to accomplish this. I considered recursion as well.
The order of the already sorted array is not based on Id - it is arbitrary. So the order needs to be preserved regardless.
Assuming same depth and all Id's exist in each level of each object use a recursive function that matches using Array#findIndex() in sort callback
function sortChildren(main, other) {
other.forEach((o, i) => {
if (o.children) {
const mChilds = main[i].children, oChilds = o.children;
oChilds.sort((a, b) => {
return mChilds.findIndex(main => main.Id === a.Id) - mChilds.findIndex(main => main.Id === b.Id)
});
// call function again on this level passing appropriate children arrays in
sortChildren(mChilds, oChilds)
}
})
}
sortChildren(data, newData);
console.log(JSON.stringify(newData, null, ' '))
<script>
var data = [{
"Id": "1",
"Children": [{
"Id": "2",
"Children": [{
"Id": "3",
"DisplayName": "1-2",
},
{
"Id": "4",
"DisplayName": "3-4",
},
]
}]
}]
var newData = [{
"Id": "1",
"Children": [{
"Id": "2",
"Children": [{
"Id": "4",
"DisplayName": "3-4",
},
{
"Id": "3",
"DisplayName": "1-2",
},
]
}]
}]
</script>

Filter an array of objects / convert array into another

could you please help me to convert data in format like :
"tanks": [
{
"id": "1",
"name": {
"id": 1,
"tor": "000"
},
"type": {
"id": 1,
"system": "CV-001"
}
}
]
into
"tanks":[
{
"type": 1,
"name": 1
}
]
As you can see, type.id in the first array is the same as just type in the second. It is like I have to iterate through the array(as I have not only one Object in it) and left only needed fields in Objects, but I am stuck.
Hope it is a little informative for you.
You can do this with a simple Array.map()
var obj = {
tanks : [
{
"id": "1",
"name": {
"id": 1,
"tor": "000"
},
"type": {
"id": 1,
"system": "CV-001"
}
},
{
"id": "2",
"name": {
"id": 2,
"tor": "200"
},
"type": {
"id": 2,
"system": "CV-002"
}
}
]
};
obj.tanks = obj.tanks.map(function(item) {
return {
name : item.name.id,
type : item.type.id
};
});
console.log(obj);
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

How to manipulate this JSON using Javascript

I am getting this response from an API:
{
"statuses": {
"status": [
{
"name": "Member",
"id": "1"
},
{
"name": "Attender",
"id": "3"
},
{
"name": "Child",
"id": "4"
}
]
}
}
But I need to somehow flatten the response to be this:
{
"name": "Member",
"id": "1"
},
{
"name": "Attender",
"id": "3"
},
{
"name": "Child",
"id": "4"
}
How can I do that using Javascript?
var response = {
"statuses": {
"status": [
{
"name": "Member",
"id": "1"
},
{
"name": "Attender",
"id": "3"
},
{
"name": "Child",
"id": "4"
}
]
}
}
var statusObj = response.statuses.status;
$('#result').text('First name is: ' + statusObj[0].name)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label id="result"/>
You can do JSON.parse(str) and then you you just take the data from status[x]
If you really want to keep it as a string you can do
var content = str.match(/\[(.*?)\]/);
In fact, you just need to retrieve by response.statuses.status from your Javascript object.
But , If you needed to convert json to javascript object,
please use JSON.parse(your json response) method using JSON.js.
Download the JSON.js from https://github.com/douglascrockford/JSON-js

Categories

Resources