Splitting object of nth length into one array - javascript

I'm given an Object of n length, with x amount of arrays in the object. I would like not to include the 0's, and to be sorted in descending order.
I've made a simple solution, that takes the value in each object, and takes the nth value and puts that in an array, but am looking for something more robust and shorter; any help would be helpful!
const arr = {
"rows": [{
"value": "demo value 1",
"data": [15, 45, 0, 0]
}, {
"value": "demo value 2",
"data": [11, 87, 0, 0]
}, {
"value": "demo value 3",
"data": [8, 113, 0, 0]
}, {
"value": "demo value 4",
"data": [7, 26, 0, 2]
}, {
"value": "demo value 5",
"data": [7, 3, 0, 0]
}, {
"value": "demo value 6",
"data": [6, 17, 0, 1]
}]
};
let newArr = [];
let newArr2 = [];
let newArr3 = [];
let newArr4 = [];
for (i = 0; i < arr.rows.length; i++) {
if (arr.rows[i].data[0] != 0)
newArr.push({
value: arr.rows[i].value,
data: arr.rows[i].data[0]
})
if (arr.rows[i].data[1] != 0)
newArr2.push({
value: arr.rows[i].value,
data: arr.rows[i].data[1]
})
if (arr.rows[i].data[2] != 0)
newArr3.push({
value: arr.rows[i].value,
data: arr.rows[i].data[2]
})
if (arr.rows[i].data[3] != 0)
newArr4.push({
value: arr.rows[i].value,
data: arr.rows[i].data[3]
})
/// ... and so on
}
console.log(newArr)
console.log(newArr2)
console.log(newArr3)
console.log(newArr4)
EDIT:
Expected result:
[
[
{
"value": "demo value 1",
"data": 15
},
{
"value": "demo value 2",
"data": 11
},
{
"value": "demo value 3",
"data": 8
},
{
"value": "demo value 4",
"data": 7
},
{
"value": "demo value 5",
"data": 7
},
{
"value": "demo value 6",
"data": 6
}
],
[
{
"value": "demo value 3",
"data": 113
},
{
"value": "demo value 2",
"data": 87
},
{
"value": "demo value 1",
"data": 45
},
{
"value": "demo value 4",
"data": 26
},
{
"value": "demo value 6",
"data": 17
},
{
"value": "demo value 5",
"data": 3
}
],
[],
[
{
"value": "demo value 4",
"data": 2
},
{
"value": "demo value 6",
"data": 1
}
]
]

I'm not quite sure if this is what you're after as there is no "expected format" provided - however this may put you on the right track
let new_arrays = [];
for (let i = 0; i < arr.rows.length; i++) {
let current_row = arr.rows[i];
for (let j = 0; j < current_row.data.length; j++) {
let current_data = current_row.data[j];
if(current_data === 0){
continue;
}
if(new_arrays[j] === undefined){
new_arrays[j] = [];
}
new_arrays[j].push({
value: current_row.value,
data : current_data,
});
}
}
console.log(new_arrays);
NOTE: if all values at an index are 0 (or the index doesn't exist), there will be no "new array" at that index

Related

Count key values from a nested object array

I have an array like this:
[
{
"costs": [{
"value": "80"
}],
"id": 4,
"name": "Subscription Fee",
"month": "March"
},
[
{
"costs": [{
"value": "200"
}],
"id": 2,
"name": "Tution",
"month": "March"
},
{
"costs": [{
"value": "10"
}],
"id": 11,
"name": "DEMO"
}
]
]
I need to have sumation of all the values from costs. How can i do that?
const data = [
{"costs":[{"value":"80"}],"id":4,"name":"Subscription Fee","month":"March"},
[
{"costs":[{"value":"200"}],"id":2,"name":"Tution","month":"March"},
{"costs":[{"value":"10"}],"id":11,"name":"DEMO"}
]
];
// flatten the arrays to get a list of objects
// iterate over this list
const res = data.flat().reduce((total, { costs = [] }) => {
// add the values of this item's costs with total
costs.forEach(({ value = 0 }) => total += +value);
return total;
}, 0);
console.log(res);

Copy second nested array of objects into first nested array of objects

How can I assign key value from array of object to another array object
I would like to assign the key:value pair to the existing array of object from the another array of objects.
I have check this thread but it is not working in my case.
I have tried something like this but that is not returning the desired output that I am looking for.
const DataA = {
"id": 57,
"status": true,
"options": [{ "id": 1, "name": "Type A" },
{ "id": 2, "name": "Type B" },
{ "id": 3, "name": "Type C" }]
}
const DataB = {
"id": 57,
"status": true,
"options": [{ "id": 1, "value": 10 },
{ "id": 2, "value": 20 },
{ "id": 3, "value": 30 }]
}
let result;
var A1 = DataA.options.map((v) => {
console.log(v);
result = v;
})
var A2 = DataB.options.map(v => {
result.options = v;
console.log("result",result);
})
let arr3 = DataA.options.map((item, i) => Object.assign({}, item, DataB[i]));
console.log(arr3);
Result will be I need as below:
const DataA = {
"id": 57,
"status": true,
"options": [{ "id": 1, "name": "Type A", "value": 10 },
{ "id": 2, "name": "Type B", "value": 20 },
{ "id": 3, "name": "Type C", "value": 30 }]
}
I need to merge the deep clone of the array that is slightly different from this thread.
The linked duplicate does actually address your question, but you need to adjust it to your situation and not just copy paste.
DataA.options = DataA.options.map((item, i) => Object.assign({}, item, DataB.options[i]));
but since this mutates the original DataA object anyway, you may as well just use forEach() and avoid creating the intermediate array from .map().
DataA.options.forEach((item, i) => Object.assign(item, DataB.options[i]));
Both of the above assume that the options arrays of both objects are a. of the same length, and b. sorted by id. To avoid these assumptions you can use .find() to look for matching elements instead of relying on index.
DataA.options.forEach(item =>
Object.assign(item, DataB.options.find(({ id }) => id === item.id)));
const DataA = {
"id": 57,
"status": true,
"options": [
{ "id": 1, "name": "Type A" },
{ "id": 2, "name": "Type B" },
{ "id": 3, "name": "Type C" }]
}
const DataB = {
"id": 57,
"status": true,
"options": [
{ "id": 1, "value": 10 },
{ "id": 2, "value": 20 },
{ "id": 3, "value": 30 }]
}
DataA.options.forEach(item =>
Object.assign(item, DataB.options.find(({ id }) => id === item.id)));
console.log(DataA)
.as-console-wrapper { max-height: 100% !important; top: 0; }

Look up values in an array using looping forEach Google Apps Script Javascript

I have an object that looks like the following {key: id numbers}
var obj = {
"c4ecb": {id: [3]},
"a4269": {id: [34,36]},
"d76fa": {id: [54,55,60,61]},
"58cb5": {id: [67]}
}
How do I loop each above id in the following array, and return the label?
var response =
{
"success": true,
"data": [
{
"key": "c4ecb",
"name": "fruits",
"options": [
{
"label": "strawberry",
"id": 3
},
{
"label": "apple",
"id": 4
},
{
"label": "pineapple",
"id": 5
},
{
"label": "Other",
"id": 31
}
],
}
]
},
{
"success": true,
"data": [
{
"key": "a4269",
"name": "vegetables",
"options": [
{
"label": "lettuce",
"id": 34
},
{
"label": "cucumber",
"id": 35
},
{
"label": "radish",
"id": 36
}
],
}
]
},
{
"success": true,
"data": [
{
"key": "d76fa",
"name": "pasta",
"options": [
{
"label": "spaghetti",
"id": 54
},
{
"label": "rigatoni",
"id": 55
},
{
"label": "linguine",
"id": 56
},
{
"label": "lasagna",
"id": 60
},
{
"label": "fettuccine",
"id": 61
}
],
}
]
}
Finally, what I want to do is look up the key and return a string of id values.
For example, input c4ecb and output strawberry. Input a4269 and output lettuce, radish. Input d76fa and output "spaghetti, rigatoni, lasagna, fettuccine"
I think to join the multiple labels output into one string I could use something like
array.data.vegetables.map(vegetables => vegetables.value).join(', ')].toString();
So in the end I want to have something like
var fruits = [some code that outputs "strawberry"];
var vegetables = [some code that outputs "lettuce, radish"];
var pasta = [some code that outputs "spaghetti, rigatoni, lasagna, fettuccine"];
What I've tried so far:
The following loop will return the id only if there is one id to be called for: e.g. only in case one where {id: 3} but returns null in cases like {id: 34,36} (because it's looking for '34,36' in id, which doesn't exist - I need to look for each one individually.
response.data.forEach(({key, options}) => {
if (obj[key]) {
options.forEach(({id, label}) => {
if (id == obj[key].id) obj[key].label = label;
});
}
});
console.log(obj)
Filter the response object to focus on the category that matches the id.
Map over the options array and select the items which appear in obj[id].
Finally convert the filtered results to a string.
See filteredLabelsAsString() function below for implementation.
var obj = {
"c4ecb": {"id": [3]},
"a4269": {"id": [34,36]},
"d76fa": {"id": [54,55,60,61]},
"58cb5": {"id": [67]}
}
var response =
[{
"success": true,
"data": [
{
"key": "c4ecb",
"name": "fruits",
"options": [
{
"label": "strawberry",
"id": 3
},
{
"label": "apple",
"id": 4
},
{
"label": "pineapple",
"id": 5
},
{
"label": "Other",
"id": 31
}
],
}
]
},
{
"success": true,
"data": [
{
"key": "a4269",
"name": "vegetables",
"options": [
{
"label": "lettuce",
"id": 34
},
{
"label": "cucumber",
"id": 35
},
{
"label": "radish",
"id": 36
}
],
}
]
},
{
"success": true,
"data": [
{
"key": "d76fa",
"name": "pasta",
"options": [
{
"label": "spaghetti",
"id": 54
},
{
"label": "rigatoni",
"id": 55
},
{
"label": "linguine",
"id": 56
},
{
"label": "lasagna",
"id": 60
},
{
"label": "fettuccine",
"id": 61
}
],
}
]
}];
function filteredLabelsAsString(obj_key, obj, content=response) {
// sanity check: obj must contain obj_key
if (Object.keys(obj).includes(obj_key)) {
return content.filter((item) => {
// filter content using value of obj_key
return item.data[0].key == obj_key;
}).map((item) => {
// item : { success: true, data: [] }
// map over options array
return item.data[0].options.map((opt) => {
// option : {id, label}
// return the label if the id is in the obj object's list
if (obj[item.data[0].key].id.includes(opt.id))
return opt.label;
}).filter((label) => {
// filter out empty items
return label !== undefined;
});
}).join(",");
}
// if obj does not contain obj_key return empty string
return "";
}
console.log("fruits: " + filteredLabelsAsString("c4ecb", obj));
console.log("vegetables: " + filteredLabelsAsString("a4269", obj));
console.log("pasta: " + filteredLabelsAsString("d76fa", obj));

Javascript create 2 arrays from object data

I have some data and I need a loop which creates 2 arrays...
So I first create the 2 arrays:
namelist = [];
countList = [];
{
"id": "622",
"name": "main",
"sub": {
"637": {
"id": "637",
"name": "name 1",
"stats": {
"count": 5
}
},
"638": {
"id": "638",
"name": "name 2",
"stats": {
"count": 10
}
}
}
}
The desired result for this example would be:
For namelist:
['name 1', 'name 2']
For countList:
[5, 10]
How can I do this?
var nameList = [];
var countList = [];
var myObj =
{
"id": "622",
"name": "main",
"sub": {
"637": {
"id": "637",
"name": "name 1",
"stats": {
"count": 5
}
},
"638": {
"id": "638",
"name": "name 2",
"stats": {
"count": 10
}
}
}
};
for(var key in myObj.sub){
nameList.push(myObj.sub[key].name);
countList.push(myObj.sub[key].stats.count);
}
console.log(nameList);
console.log(countList);
for(var key in obj.sub){
nameList.push(obj.sub[key].name);
countList.push(obj.sub[key].stats.count;
}
Object.keys may help you to walk through object properties. Example related to your object:
var namelist = [],
countList = [],
obj = {
"id": "622",
"name": "main",
"sub": {
"637": {
"id": "637",
"name": "name 1",
"stats": {
"count": 5
}
},
"638": {
"id": "638",
"name": "name 2",
"stats": {
"count": 10
}
}
}
};
Object.keys(obj.sub).forEach(function(item) {
namelist.push(obj.sub[item].name);
countList.push(obj.sub[item].stats.count);
});
console.log(namelist, countList);
Working example: https://jsfiddle.net/ry0zqweL/
Obviously, you can optimise it in many ways. It's just illustrating one of the many solutions.

Joining 2 JSON arrays, only taking the matches

I have 2 JSON arrays, both of which can contain nested arrays:
var serverArr = [
{ "id": 1, "text": "Item 1" },
{ "id": 2, "text": "Item 2" },
{ "id": 3, "text": "Item 3", "children": [{ "id": 20, "text": "Item 20" },
{ "id": 21, "text": "Item 21" }] },
{ "id": 4, "text": "Item 4" }
];
var userArr = [
{ "id": 1, "text": "Item 1" },
{ "id": 3, "text": "Item 3", "children": [{ "id": 20, "text": "Item 20" },
{ "id": 25, "text": "Item 25" }] },
{ "id": 5, "text": "Item 5" }
];
What I need to do is combine them into 1 array, only taking the matching values. So the result should look like:
[{ "id": 1, "text": "Item 1" },
{ "id": 3, "text": "Item 3", "children": [{ "id": 20, "text": "Item 20" }]}];
I'm using the results with the jsTree plugin, so the format has to be like this unfortunately.
How can I get the end result from those 2 arrays?
I have defined a function that does 3 things to solve this problem
First thing it gets all the elements that are in both arrays and it collects all childs for every item in both arrays
Second thing is filtering all the childs elements to keep only unique ones
Third thing is changing the children of the parent elements to keep only unique ones
function combine(array1,array2)
{
result = serverArr.concat(userArr);
var childs = [];
// First step
result = result.filter(function(elem, index, self)
{
if(elem.children != undefined)
childs[elem.id] = ((childs[elem.id] == undefined) ? [] : childs[elem.id]).concat(elem.children);
for (key in self)
if(key < index && elem.id == self[key].id )
return true;
return false;
});
// Second step
for(i in childs)
childs[i] = childs[i].filter(function(elem, index, self)
{
for (key in self)
if(key < index && JSON.stringify(elem) == JSON.stringify(self[key]) )
return true;
return false;
});
//Third step
for(key in result)
if(childs[result[key].id] != undefined)
result[key].children = childs[result[key].id];
return result;
}

Categories