merge array object with pure JavaScript - javascript

I need to merge two arrays with objects inside with JavaScript.
How can this be done?
I am currently using this code, but it is not for me:
var array_merge = [];
var array_one = [
{
label: "label",
value: "value",
},
{
label: "label",
value: "value",
},
];
array_merge.push(array_one);
var array_two = [
{
label: "label",
value: "value",
},
{
label: "label",
value: "value",
},
];
array_merge.push(array_two);
How can I join them so that the result is the following?
var array_merge = [
{
label: "label",
value: "value",
},
{
label: "label",
value: "value",
},
{
label: "label",
value: "value",
},
{
label: "label",
value: "value",
},
];
Thanks.

You can use the concat method to merge arrays
The concat() method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array.
const array_one = [
{
label: "label",
value: "value",
},
{
label: "label",
value: "value",
},
];
const array_two = [
{
label: "label",
value: "value",
},
{
label: "label",
value: "value",
},
];
const array_merge = array_one.concat(array_two);
console.log(array_merge)

Related

Update array of objects based on the object passed

I have an array of objects that has the following format,
const options = [
{ key: 1, text: "Name", value: "name", icon: "sort" },
{ key: 2, text: "Time", value: "time", icon: "sort" },
{ key: 3, text: "Type", value: "type", icon: "sort" }
];
Now based on the input passed which of format {fieldName,order} I have to modify the array. Basically order will take two values "asc" or "desc" and the fieldName will take any of the values in the value property of options array.
For Example : { fieldName: "name", order : "asc"} or { fieldName: "type", order: "desc"}
Now basically based this order , I have modify the icon field of the source array for that field.
If order is asc, then change the icon property for that field to sort up .If its order is desc, then change the icon property for that field to sort down
Example
1) sortBy: { fielName: "name", order:"asc"}
//Output
[
{ key: 1, text: "Name", value: "name", icon: "sort up" },
{ key: 2, text: "Time", value: "time", icon: "sort" },
{ key: 3, text: "Type", value: "type", icon: "sort" }
];
2) sortBy: { fielName: "type", order:"desc"}
//Output
[
{ key: 1, text: "Name", value: "name", icon: "sort" },
{ key: 2, text: "Time", value: "time", icon: "sort" },
{ key: 3, text: "Type", value: "type", icon: "sort down"}
];
It should update icon only of the field passed to it, and rest fields icon should be set to "sort"
This is what I tried
const options = [
{ key: 1, text: "Name", value: "name", icon: "sort" },
{ key: 2, text: "Time", value: "time", icon: "sort" },
{ key: 3, text: "Type", value: "type", icon: "sort" }
];
function updateArray(obj)
{
const newArr = options.map(item => {
if(item.name === obj.fieldName) {
return {...item, icon: obj.order === "desc" ? "sort-desc" :"sort-asc" };
}
return {...item};
});
return newArr;
}
Try this
const options = [
{ key: 1, text: "Name", value: "name", icon: "sort" },
{ key: 2, text: "Time", value: "time", icon: "sort" },
{ key: 3, text: "Type", value: "type", icon: "sort" }
];
function sorta(op,options){
field =op.fielName
newarray=[]
options.forEach(o=>{
if(o.value==field){
op.order=="asc"?f="up":f="down"
o.icon="sort-"+f
newarray.push(o)
}
else newarray.push(o)
})
return newarray
}
console.log(sorta({ fielName: "name", order:"asc"},options ))
Your function works, but you are trying to access a non-existent property.
I believe it should be:
if(item.value === obj.fieldName) {
...
}
Demo:
const options = [
{ key: 1, text: "Name", value: "name", icon: "sort" },
{ key: 2, text: "Time", value: "time", icon: "sort" },
{ key: 3, text: "Type", value: "type", icon: "sort" }
];
function updateArray(obj)
{
const newArr = options.map(item => {
if(item.value === obj.fieldName) {
return {...item, icon: obj.order === "desc" ? "sort-desc" :"sort-asc" };
}
return {...item};
});
return newArr;
};
console.log(updateArray({fieldName: 'type', order: 'desc'}));
console.log(updateArray({fieldName: 'time', order: 'asc'}));
console.log(updateArray({fieldName: 'name', order: 'desc'}));

How to covert object array to Array List using for loop

Hey I am trying to convert object in array list i tried a lot of but i could not convert here is the code that i tried
const dat1 = [];
for (let i = 0; i < topology.length; i++) {
const data = [data1[i]];
dat1.push({
value:data
});
}
Here is the result that i got of value .
const topology = [
{
label: "secondary",
value: 0.10558737933770979
},
{
label: "unclassified",
value: 0.07702637029193307
},
{
label: "residential",
value: 0.05898100977978933
},
{
label: "tertiary",
value: 0.3012573789201084
},
{
label: "primary",
value: 0.44342463442819086
},
{
label: "primary_link",
value: 0.013723227242268547
},
];
and Here is the result that i want value look like in Array form.
const topology = [
{
label: "secondary",
value: [0.10558737933770979]
},
{
label: "unclassified",
value: [0.07702637029193307]
},
{
label: "residential",
value: [0.05898100977978933]
},
{
label: "tertiary",
value: [0.3012573789201084]
},
{
label: "primary",
value: [0.44342463442819086]
},
{
label: "primary_link",
value: [0.01372322724226854]
},
];
You could map the original topology and then just return the value wrapped in an array, like so:
const topology = [
{
label: "secondary",
value: 0.10558737933770979,
},
{
label: "unclassified",
value: 0.07702637029193307,
},
{
label: "residential",
value: 0.05898100977978933,
},
{
label: "tertiary",
value: 0.3012573789201084,
},
{
label: "primary",
value: 0.44342463442819086,
},
{
label: "primary_link",
value: 0.013723227242268547,
},
];
let result = topology.map(({ label, value }) => ({ label, value: [value] }));
console.log(result);
You can also follow your approach, like so:
const data1 = [];
for (let i = 0; i < topology.length; i++) {
const data = [topology[i].value];
data1.push({
label: topology[i].label,
value: data,
});
}
You were very close, just missing getting the value to be wrapped, i.e. you want the "old data", not the current new, so not [data1[i]] but [topology[i].value] and then adding the label to the new object in data1 array.
const topology = [
{
label: "secondary",
value: 0.10558737933770979,
},
{
label: "unclassified",
value: 0.07702637029193307,
},
{
label: "residential",
value: 0.05898100977978933,
},
{
label: "tertiary",
value: 0.3012573789201084,
},
{
label: "primary",
value: 0.44342463442819086,
},
{
label: "primary_link",
value: 0.013723227242268547,
},
];
const data1 = [];
for (let i = 0; i < topology.length; i++) {
const data = [topology[i].value];
data1.push({
label: topology[i].label,
value: data,
});
}
console.log(data1);
You could do something like this:
const changed = topology.map(({ label, value }) => ({
label,
value: [value]
}));
Basically just transforms the original data to wrap the value as an array with a single element.

Transforming array of objects based upon key - javascript

I am trying to figure out the most efficient method for reducing an array of objects based upon a unique key (key/values are dynamically returned in this case). I've tried to a combination of different methods using concat, map, or filter but haven't had much luck.
Original array of objects:
[
{
key: "Name",
value: "John"
},
{
key: "Company",
value: "Acme"
},
{
key: "Name",
value: "Jack"
},
{
key: "Name",
value: "Matt"
},
{
key: "Last",
value: "Test"
}
]
Desired Array:
[
{
key: "Name",
values: [
"John",
"Jack",
"Matt"
]
},
{
key: "Company",
values: [
"Acme"
]
},
{
key: "Last",
values: [
"Test"
]
}
]
Prob other ways, but a simple for loop would suffice:
const data = [{
key: "Name",
value: "John"
},
{
key: "Company",
value: "Acme"
},
{
key: "Name",
value: "Jack"
},
{
key: "Name",
value: "Matt"
},
{
key: "Last",
value: "Test"
}
]
let result = {}
for (const i in data) {
result[data[i].key] = {
key: data[i].key,
values: [
...result[data[i].key] ? result[data[i].key].values : [],
data[i].value
]
}
}
console.log(Object.values(result))
You can use reduce to build a new object using name as the keys, and then use Object.values to create the output you need from the object:
const data = [
{ key: "Name", value: "John" },
{ key: "Company", value: "Acme" },
{ key: "Name", value: "Jack" },
{ key: "Name", value: "Matt" },
{ key: "Last", value: "Test" }
];
const out = Object.values(data.reduce((acc, { key, value }) => {
// If the key doesn't exist on the object, add it
// and initialise the value object
acc[key] = acc[key] || { key, values: [] };
// Push the value from the current iteration
// into the values array
acc[key].values.push(value);
// Return the accumulator for the next iteration
return acc;
}, {}));
console.log(out);
I think reduce is the best solution here :)
const initialArray = [
{
key: "Name",
value: "John"
},
{
key: "Company",
value: "Acme"
},
{
key: "Name",
value: "Jack"
},
{
key: "Name",
value: "Matt"
},
{
key: "Last",
value: "Test"
}
];
const result = initialArray.reduce((acc, obj) => {
/* try to find object in the result array
returns index or -1 if object is missing
*/
const existingIndex = acc.findIndex(item => item.key === obj.key);
if (existingIndex > -1) {
/* object already exists, update its values array */
acc[existingIndex].values.push(obj.value);
return acc;
} else {
/* the key is first encountered, create an object in the result array */
acc.push({
key: obj.key,
values: [obj.value],
});
return acc;
}
}, []); // [] - default value is an empty array
console.log(result);

Group and Stack data in Kendo UI Chart

I have a json data like:
arr = [{ Name: 'PAVI', value: 3}, {Name: 'Crystal', value: 2}, {Name: 'PAVI', value: 6}, {Name: 'Crystal', value: 11}]
How to stack data with similar Name in Kendo UI Chart? Here is my code for this moment
$("#chart").kendoChart({
dataSource: {
data: data,
group: {
field: 'Name'
}
},
series: [{
name: "Total Sales",
field: "value",
stack: true
}],
categoryAxis: {
field: 'Name'
},
Actually here is the structure of real data that i use
{
Account:"Piscopo Cash and Carry"
AccountName:"Piscopo Cash and Carry"
Category:""
MainCategory:"Other"
TotalQty:146
TotalSales:9747.616
}
UPDATE
I found the solution by setting group to MainCategory (dont even think that solution is so simple XD )
I'm not sure what you meant by "stack" because with that data structure, I don't see any way how you could stack it. However, if you wanted to sum the values with the same name and show the total, then you can use the aggregate option in the chart.
Here's how to do that: This will sum PAVI's & Crystal's values and show only two columns in the chart.
var dataSource = new kendo.data.DataSource({
data: data,
group: {
field: "Name", aggregates: [{
field: "value", aggregate: "sum"
}]
}
});
Notice the group and aggregate options.
Here's the full code:
var data = [
{ Name: 'PAVI', value: 3 },
{ Name: 'Crystal', value: 2 },
{ Name: 'PAVI', value: 3 },
{ Name: 'Crystal', value: 10 }
];
var dataSource = new kendo.data.DataSource({
data: data,
group: {
field: "Name", aggregates: [{
field: "value", aggregate: "sum"
}]
}
});
dataSource.read();
$("#chart").kendoChart({
dataSource: getChartData(dataSource),
series: [{
type: "column",
field: "value",
categoryField: "Name"
}]
});
function getChartData(dataSource) {
var chartData = [];
var view = dataSource.view();
for (var idx = 0; idx < view.length; idx++) {
chartData.push({
Name: view[idx].value,
value: view[idx].aggregates.value.sum
});
}
return chartData;
}
Here's a Fiddle
Hope it helps :) Feel free to ask if you have any doubts.

How to make morris donut chart with ajax json?

How to make morris donut chart with ajax json ?
this is my code :
$(function() {
$.ajax({
url : 'dashboard/total-data',
}).done(function(data){
initDonut(JSON.parse(data));
console.log(data);
}).fail(function(){
});
var initDonut = function(data){
return Morris.Donut({
element: 'morris-donut-chart',
data: [ data ],
// data: [
// {label: "BMW", value: 4},
// {label: "Mercy", value: 0},
// {label: "Ferrari", value: 0},
// {label: "Toyota", value: 3},
// {label: "Porsche", value: 0},
// {label: "Limosin", value: 0},
// {label: "Lamborgini", value: 3} ],
resize: true,
colors: ['#87d6c6', '#54cdb4','#1ab394', '#54cdb4','#1ab394', '#54cdb4','#1ab394'],
});
} });
Ajax code above return data format like this:
{"BMW":4,"Mercy":0,"Ferrari":0,"Toyota":3,"Porsche":0,"Limosin":0,"Lamborgini":3}
my question,
How to make format data above become like this with javascript?
[ {label: "BMW", value: 4},{label: "Mercy", value: 0},{label: "Ferrari", value: 0},{label: "Toyota", value: 3},{label: "Porsche", value: 0},{label: "Limosin", value: 0},{label: "Lamborgini", value: 3} ]
This is code for show json:
public function total_data()
{
$data['BMW'] = $this->m_dashboard->get_total_product_bmw();
$data['Mercy'] = $this->m_dashboard->get_total_product_mercy();
echo json_encode($data);
$data['Ferrari'] = $this->m_dashboard->get_total_product_ferrari();
$data['Toyota'] = $this->m_dashboard->get_total_product_toyota();
$data['Porsche'] = $this->m_dashboard->get_total_product_porsche();
$data['Limosin'] = $this->m_dashboard->get_total_product_limosin();
$data['Lamborgini'] = $this->m_dashboard->get_total_product_lamborgini();
echo json_encode($data);
}
You need to change code of total-data like below:-
public function total_data()
{
$data[0]['label']= 'BMW';
$data[0]['value']= $this->m_dashboard->get_total_product_bmw();
$data[1]['label']= 'Mercy';
$data[1]['value']= $this->m_dashboard->get_total_product_mercy();
$data[2]['label']= 'Ferrari';
$data[2]['value']= $this->m_dashboard->get_total_product_ferrari();
$data[3]['label']= 'Toyota';
$data[3]['value']= $this->m_dashboard->get_total_product_toyota();
$data[4]['label']= 'Porsche';
$data[4]['value']= $this->m_dashboard->get_total_product_porsche();
$data[5]['label']= 'Limosin';
$data[5]['value']= $this->m_dashboard->get_total_product_limosin();
$data[6]['label']= 'Lamborgini';
$data[6]['value']= $this->m_dashboard->get_total_product_lamborgini();
echo json_encode($data);
}
jQuery code need to be:-
$(function() {
$.ajax({
url : 'dashboard/total-data',
}).done(function(data){
Morris.Donut({
element: 'morris-donut-chart',
data: JSON.parse(data),
resize: true,
colors: ['#87d6c6', '#54cdb4','#1ab394', '#54cdb4','#1ab394', '#54cdb4','#1ab394']
});
}).fail(function(){
});
});
Working at my end:- http://prntscr.com/f6399z
It seems like the question is mostly, how do I get from
{key: foo, key2:bar}
to
[{label: key, value:foo},{label: key2, value:bar}]
I'm a huge fan of libraries like lodash and ramda. If you had Ramda available I would recommend something like:
var input = {
"BMW": 4,
"Mercy": 0,
"Ferrari": 0,
"Toyota": 3,
"Porsche": 0,
"Limosin": 0,
"Lamborgini": 3
}
var expected = [{
label: "BMW",
value: 4
}, {
label: "Mercy",
value: 0
}, {
label: "Ferrari",
value: 0
}, {
label: "Toyota",
value: 3
}, {
label: "Porsche",
value: 0
}, {
label: "Limosin",
value: 0
}, {
label: "Lamborgini",
value: 3
}]
// First thing we want is to group the key and value together
var pairs = R.toPairs(input);
// This gives us something like
// [["BMW",4],["Mercy",0],...]
// This is getting a little far to explain here but Ramda
// curries all it's functions so we can pass the labels
// here and then the pairs later.
var label = R.zipObj(["label", "value"]);
// Here we map the label function over each set of pairs
var output = pairs.map(label);
tape('Same?', t => {
t.deepEqual(expected, output);
t.end();
});
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.23.0/ramda.min.js"></script>
<script src="https://wzrd.in/standalone/tape#latest"></script>
Otherwise, you could do something in a for loop.
var input = {
"BMW": 4,
"Mercy": 0,
"Ferrari": 0,
"Toyota": 3,
"Porsche": 0,
"Limosin": 0,
"Lamborgini": 3
}
var expected = [{
label: "BMW",
value: 4
}, {
label: "Mercy",
value: 0
}, {
label: "Ferrari",
value: 0
}, {
label: "Toyota",
value: 3
}, {
label: "Porsche",
value: 0
}, {
label: "Limosin",
value: 0
}, {
label: "Lamborgini",
value: 3
}]
var output = [];
for (var k in input) {
output.push({"label": k, "value": input[k]});
}
tape('Same?', t => {
t.deepEqual(expected, output);
t.end();
});
<script src="https://wzrd.in/standalone/tape#latest"></script>

Categories

Resources