How to add multiple ids and content? - javascript

Javascript
In a constructor and I want to manipulate it and want to add as many ids and content as much as I want.
var groups = new vis.DataSet([
{ id: 1, content: "" },
{ id: 2, content: "" },
{ id: 3, content: "" },
{ id: 4, content: "" },
]);

I am not 100% sure what you're asking for, so here are two solutions.
As Insyri mentioned in the comments, you should utilize the spread syntax. You could do something along the lines of this:
var groups = [
{ id: 1, content: 'abc' },
{ id: 2, content: 'cba' },
{ id: 3, content: '123' },
{ id: 4, content: '321' },
];
class someClass {
constructor(...data) {
this.key = data;
}
}
const test = new someClass(...groups);
console.log(test)
The output of the console log will look like this:
someClass {
key: [
{ id: 1, content: 'abc' },
{ id: 2, content: 'cba' },
{ id: 3, content: '123' },
{ id: 4, content: '321' }
]
}
If you want all of the objects to have a unique key (of whatever you want), you can do this:
class otherClass {
constructor(...data) {
data.forEach(obj=>{
this[obj.id] = obj
})
}
}
const test2 = new otherClass(...groups);
console.log(test2)
Output:
otherClass {
'1': { id: 1, content: 'abc' },
'2': { id: 2, content: 'cba' },
'3': { id: 3, content: '123' },
'4': { id: 4, content: '321' }
}

Related

Array javascript to match answer and questions by id

I have an array form lke this
const options = [
{
id: 1,
content: 'Hello'
},
{
id: 2,
content: 'Hi'
}
]
const answers = [
{
id: 400,
content: 'World',
optionKey: 1
},
{
id: 500,
content: 'There',
optionKey: 2
}
]
expected output
const expecetedOutput = [
{
option: {
id: 1,
content: 'Hello'
},
answer: {
id: 400,
content: 'World'
}
},
{
option: {
id: 2,
content: 'Hi'
},
answer: {
id: 500,
content: 'There'
}
}
];
What i have tried
i have tried using map and find but the result still not as expected
const optionWithAnswer = answers.map((answer) => {
return {
option: options.find((option) => option.id === answer.optionKey),
answer: answers.find((answer) => answer.optionKey === options.find((option) => option.id === answer.optionKey).id)
}
})
result i got. the answer will always found the first index of answer array
[
{
option: { id: 1, content: 'Hello' },
answer: { id: 400, content: 'World', optionKey: 1 }
},
{
option: { id: 2, content: 'Hi' },
answer: { id: 400, content: 'World', optionKey: 1 }
}
]
what i'm supposed to do. is this something that should accomplish using reduce ?
options.map(opt => ({
option: opt,
answer: answers.find(i => i.optionKey === opt.id)
}));

Recursively get all children

I need to recursively get all children from a nested object.
I already wrote a function that does it (kinda) but I think it can be improved.
How can I make it shorter and cleaner?
I have included the data I'm using for testing as well as the function I wrote that needs improvement.
let data = [{
id: 1,
child: {
id: 2,
child: {
id: 3,
child: {
id: 4,
child: null
}
}
}
},
{
id: 5,
child: {
id: 6,
child: null
}
}
];
// function
for (let cat of data) {
cat.children = getCategoryChild(cat);
console.log(cat.children)
}
function getCategoryChild(cat) {
let t = [];
if (cat.child != null) {
t.push(cat.child);
let y = getCategoryChild(cat.child);
if (y.length > 0) {
for (let i of y) {
t.push(i)
}
}
}
return t;
}
Expected output:
[{id: 1, children: [{id: 2}, {id: 3}, {id: 4}]}, {id: 5, children: [{id: 6}]}]
You could take a recursive approach by checking the actual child property
function convert(array) {
const iter = o => o ? [{ id: o.id }, ...iter(o.child)] : [];
return array.map(({ id, child }) => ({ id, children: iter(child) }));
}
var data = [{ id: 1, child: { id: 2, child: { id: 3, child: { id: 4, child: null } } } }, { id: 5, child: { id: 6, child: null } }];
console.log(convert(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }
assuming that each category only ever has one child
edited to adhere to the expected result...
function iterChildren(cat) {
let c = cat, children = [];
while (c.child) {
children.push({id: c.child.id});
c = c.child;
}
return {id: cat.id, children: children};
}
let newData = data.map(iterChildren);
I re-wrote the function.
It filters cats, and only returns an object with id and child_id of each.
let output = [],
data = [{
id: 1,
child: {
id: 2,
child: {
id: 3,
child: {
id: 4,
child: null
}
}
}
},
{
id: 5,
child: {
id: 6,
child: null
}
}
];
function getCategoryChild(cat) {
var t = [{
id: cat.id,
child_id: null
/* HERE you can set, what kind of data should be included to output */
}]
if (cat.child) {
t[0].child_id = cat.child.id
t = t.concat(getCategoryChild(cat.child))
}
return t
}
for (x of data) {
output=output.concat(getCategoryChild(x))
}
console.log(output)
EDIT: I edited my code assuming that one cat can have more children:
let output = [],
data = [{
id: 1,
child: {
id: 2,
child: {
id: 3,
child: {
id: 4,
child: null
}
}
}
},
{
id: 5,
child: {
id: 6,
child: null
}
},
{
id: 7,
child: [
{
id: 8,
child: {
id: 9,
child: null
}
},
{
id: 10,
child: null
},
{
id: 11,
child: null
}
]
},
];
function getCategoryChild(cat) {
var t = [{
id: cat.id,
child_id: []
/* HERE you can set, what kind of data should be included to output */
}]
if (cat.child) {
if (!(cat.child instanceof Array)) {
cat.child = [cat.child]
}
for (var x of cat.child) {
t[0].child_id.push(x.id)
t = t.concat(getCategoryChild(x))
}
}
return t
}
for (x of data) {
output = output.concat(getCategoryChild(x))
}
console.log(output)
data.map(({id,child:c})=>({id,children:[...{*0(){for(;c&&({id}=c);c=c.child)yield{id}}}[0]()]}))

JavaScript - Is there a simple way to get the values for every occurrence of a specific key in nested JSON

I have a JSON structure similar to this:
[
{
cells: [
{ id: "1", cellType: 3, widget: { id: 1, description: "myDesc"} },
{ id: "2", cellType: 4, widget: { id: 2, description: "myDesc2"} }
]
},
{
cells: [
{ id: "3", cellType: 5, widget: { id: 3, description: "myDesc3"} }
]
},
...
]
How do I get the value of every widget into a separate array using EcmaScript (or anything that's available in Angular 2+), and without using a library (including JQuery)? I need a final array like this:
[
{
id: 1,
description: "myDesc"
},
{
id: 2,
description: "myDesc2"
},
...
]
Update
(and thanks to #Felix Kling for the 1st part) - I found I can get all of the widgets with this:
JSON.parse(json)[0].forEach( c => c.cells.forEach( c2 => console.log(c2.widget)));
You can use .map() with .reduce()
let input = [
{
cells: [
{ id: "1", cellType: 3, widget: { id: 1, description: "myDesc"} },
{ id: "1", cellType: 4, widget: { id: 2, description: "myDesc2"} }
]
},
{
cells: [
{ id: "3", cellType: 5, widget: { id: 3, description: "myDesc3"} }
]
},
];
let result = input.reduce((result, current) => {
return result.concat(current.cells.map(x => x.widget));
}, [])
console.log(result);
You can use .map() and .concat() to get the desired result:
let data = [{
cells: [
{ id: "1", cellType: 3, widget: { id: 1, description: "myDesc"} },
{ id: "1", cellType: 4, widget: { id: 2, description: "myDesc2"} }
]}, {
cells: [
{ id: "3", cellType: 5, widget: { id: 3, description: "myDesc3"} }
]
}];
let result = [].concat(...data.map(({cells}) => cells.map(({widget}) => widget)));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Join two objects by key

I stuck on mergin 2 objects into one. Let's say I have 2 arrays of objects:
One is childs:
let childsWithMoreInfo = [{
id: 1,
name: 'somename',
parent: {
id: 2
},
}, {
id: 2,
name: 'some child name',
parent: {
id: 4
}
}];
And the second one is Parents:
let parents = [{
id: 1,
parentName: 'The first',
child: {}
}, {
id: 2,
parentName: 'The second',
child: {}
}, {
id: 3,
parentName: 'The third',
child: {}
}, {
id: 4,
parentName: 'The fourth',
child: {}
}];
And I would to merge these objects like this:
let combined = [
{
id: 1,
parentName: The first,
child: {}
},
{
id: 2,
parentName: The second,
child: {
id: 1,
name: somename,
}
},
{
id: 3,
parentName: The third,
child: {}
},
{
id: 4,
parentName: The fourth,
child: {
id: 2
name: some child name,
}
},
]
];
So basically it should be something like:
let combinedList = parents.child = childsWithMoreInfo where parents.id = childsWithMoreInfo.parent.id . On which method I should take a look? Do you have any ideas how can easily achieve that?
I really know how to use forEach, I wanted to avoid it.
This is what I made:
this.combined = _.map(parents, (parent) => {
parent.child = childs.find(child => child.parent.id === parent.id);
return parent;
});
Thank you for all of your answers.
You could use a Map and iterate then with Array#forEach for every object.
Then have a lookup in the map and assign the values to ch parent object.
var childsWithMoreInfo = [{ id: 1, name: 'somename', parent: { id: 2 } }, { id: 2, name: 'some child name', parent: { id: 4 } }],
parents = [{ id: 1, parentName: 'The first', child: {} }, { id: 2, parentName: 'The second', child: {} }, { id: 3, parentName: 'The third', child: {} }, { id: 4, parentName: 'The fourth', child: {} }],
map = new Map;
parents.forEach(p => map.set(p.id, p));
childsWithMoreInfo.forEach(c => {
var o = map.get(c.parent.id);
o.child = { id: c.id, name: c.name };
});
console.log(parents);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Another solution would be the use of Array#find
var childsWithMoreInfo = [{ id: 1, name: 'somename', parent: { id: 2 } }, { id: 2, name: 'some child name', parent: { id: 4 } }],
parents = [{ id: 1, parentName: 'The first', child: {} }, { id: 2, parentName: 'The second', child: {} }, { id: 3, parentName: 'The third', child: {} }, { id: 4, parentName: 'The fourth', child: {} }];
childsWithMoreInfo.forEach(c => {
var o = parents.find(p => p.id === c.parent.id);
o.child = { id: c.id, name: c.name };
});
console.log(parents);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Following code has some pure functions to do your task. I have formatted/cleaned the input objects also:
'use strict';
let childsWithMoreInfo = [{
id: 1,
name: 'somename',
parent: {
id: 2
},
}, {
id: 2,
name: 'some child name',
parent: {
id: 4
}
}];
let parents = [{
id: 1,
parentName: 'The first',
child: {}
}, {
id: 2,
parentName: 'The second',
child: {}
}, {
id: 3,
parentName: 'The third',
child: {}
}, {
id: 4,
parentName: 'The fourth',
child: {}
}];
function makeObjectFromArray(arr) {
let obj = {};
arr.map(function(item) {
if (obj[item.id] === undefined) {
obj[item.id] = item
}
})
return obj;
}
function toArray(obj) {
return Object.keys(obj).map(function(key) {
return obj[key]
});
}
function sampleParentChildren(parent, children) {
let Parent = {};
if (parent.constructor === Array) {
Parent = makeObjectFromArray(parent);
} else {
Parent = Object.assign({}, parent)
}
children.map(function(child) {
if (Parent[child.parent.id] !== undefined) {
if (Parent[child.parent.id].child === undefined) {
Parent[child.parent.id].child = {};
}
Parent[child.parent.id].child[child.id] = child
}
});
return Parent;
}
let resampledData = sampleParentChildren(parents, childsWithMoreInfo);
console.log(resampledData, toArray(resampledData));
To join the arrays in ES6, you can use the spread operator to join the arrays and just use plain old forEach to deduping. The spread operator is more declarative than Es5's array concatenation methods as mentioned here on MDN
[...parents, ...childsWithMoreInfo]
Here's a working example:
let childsWithMoreInfo = [{
id: 1,
name: 'somename',
parent: {
id: 2
},
}, {
id: 2,
name: 'some child name',
parent: {
id: 4
}
}],
parents = [{
id: 1,
parentName: 'The first',
child: {}
}, {
id: 2,
parentName: 'The second',
child: {}
}, {
id: 3,
parentName: 'The third',
child: {}
}, {
id: 4,
parentName: 'The fourth',
child: {}
},
];
var conjoined = [...parents, ...childsWithMoreInfo];
conjoined.forEach(function(parentConjoinee, parentIndex) {
conjoined.forEach(function(childConjoinee, childIndex) {
if (parentConjoinee.id === childConjoinee.id && parentIndex !== childIndex) {
conjoined.splice(childIndex, 1);
}
});
});
console.log(conjoined);
You can use nested for loops, break
var childsWithMoreInfo = [{
id: 1,
name: "somename",
parent: {
id: 2
}
}, {
id: 2,
name: "some child name",
parent: {
id: 4
}
}];
var parents = [{
id: 1,
parentName: "The first",
child: {}
}, {
id: 2,
parentName: "The second",
child: {}
}, {
id: 3,
parentName: "The third",
child: {}
}, {
id: 4,
parentName: "The fourth",
child: {}
}
];
let combined = [];
for (var i = 0; i < parents.length; i++) {
for (var j = 0; j < childsWithMoreInfo.length; j++) {
if (childsWithMoreInfo[j].parent.id === parents[i].id) {
parents[i].child.id = childsWithMoreInfo[j].id;
parents[i].child.name = childsWithMoreInfo[j].name;
break;
}
}
combined.push(parents[i])
};
console.log(combined);

Merge two arrays into one with push()

I've got follow code:
list1 = {
Items: [
{
ID: 1,
Name: "Zurich"
},
{
ID: 2,
Name: "London"
}, {
ID: 3,
Name: "New York"
}
]
};
list2 = {
Items: [
{
ID: -1,
Name: "Dummy"
},
{
ID: 0,
Name: "Dummy2"
}
]
};
list1.push(list2);
I expect follow result:
list1:
0: Object (Zurich)
1: Object (London)
3: Object (New York)
4: Object (Dummy)
5: Object (Dummy2)
But I get this one:
list1:
0: Object (Zurich)
1: Object (London)
2: Object (New York)
3: Object (Items)
0: Object (Dummy)
1: Object (Dummy2)
How can I get my expectet result?
Thanks and cheers.
Beside Array#concat, you could use Array#push.apply for it
var list1 = { Items: [{ ID: 1, Name: "Zurich" }, { ID: 2, Name: "London" }, { ID: 3, Name: "New York" }] },
list2 = { Items: [{ ID: -1, Name: "Dummy" }, { ID: 0, Name: "Dummy2" }] };
[].push.apply(list1.Items, list2.Items);
console.log(list1);
The question was how to do this with push() not concat():
for (var i = 0; i < list2.Items.length; i++) {
list1.Items.push(list2.Items[i]);
}
Use the spread operator:
list1.Items.push(...list2.Items)
Spread is an ES2015 feature. Your target browsers or runtime may not support it yet, so check the compatibility table (or use a transpiler like babel).
list1 = {
Items: [
{
ID: 1,
Name: "Zurich"
},
{
ID: 2,
Name: "London"
}, {
ID: 3,
Name: "New York"
}
]
};
list2 = {
Items: [
{
ID: -1,
Name: "Dummy"
},
{
ID: 0,
Name: "Dummy2"
}
]
};
list1.Items = list1.Items.concat(list2.Items);
console.log(list1);
try with:
list2.items.forEach(function (item) {
list1.items.push(item)
})
You need to loop through each items in list2 and then fetch them to push into list1.. Below is the snippet using $.each
var list1 = {
Items: [
{
ID: 1,
Name: "Zurich"
},
{
ID: 2,
Name: "London"
}, {
ID: 3,
Name: "New York"
}
]
};
var list2 = {
Items: [
{
ID: -1,
Name: "Dummy"
},
{
ID: 0,
Name: "Dummy2"
}
]
};
$(list2.Items).each(function(k,v){
list1.Items.push(v);
})
console.log(list1);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Categories

Resources