push existing array into multiple arrays js - javascript

I want to create an array for active items and inactive items in my list. I currently have the below code. The below code works however I want the format to be the same as the existing array.
var myData = [
{"text" : "item 1", "id":11111, "active" : 0 },
{"text" : "item 2", "id":22222, "active" : 1 },
{"text" : "item 3", "id":33333, "active" : 1 },
{"text" : "item 4", "id":44444, "active" : 0 }
];
console.log(myData[0].text); //returns item 1
var active = [];
var inactive = [];
for (var i = 0; i < myData.length; i++) {
if(myData[i].active) {
active.push({
items: myData[i];
});
}
else {
inactive.push({
items: myData[i];
});
}
}
console.log(active[0].items.text); //returns item 2
console.log(inactive[0].items.text); //returns item 1
I can't seem to work out how to push the whole object into the array without naming it.
I want to setup my array so that I can console.log
active[0].text
rather than having to go to the next level and go
active[0].items.text
Is there a way I can push the whole object without naming it?

var myData = [
{"text" : "item 1", "id":11111, "active" : 0 },
{"text" : "item 2", "id":22222, "active" : 1 },
{"text" : "item 3", "id":33333, "active" : 1 },
{"text" : "item 4", "id":44444, "active" : 0 }
];
console.log(myData[0].text); //returns item 1
var active = myData.filter(function(data){
return data.active;
});
var inactive = myData.filter(function(data){
return !data.active;
});
Or perhaps make it a function
function getData(type){
return myData.filter(function(data){
return (type == 'active') ? data.active : !data.active;
});
}
and if you're already using ES6 arrow functions you can shorten them to:
var active = myData.filter(data => data.active);
var inactive = myData.filter(data => !data.active);
function getData(type){
return myData.filter(data => (type == 'active') ? data.active : !data.active);
}

var myData = [
{"text" : "item 1", "id":11111, "active" : 0 },
{"text" : "item 2", "id":22222, "active" : 1 },
{"text" : "item 3", "id":33333, "active" : 1 },
{"text" : "item 4", "id":44444, "active" : 0 }
];
var active = [];
var inactive = [];
for (var i in myData){
var item = myData[i];
if (item.active){
active.push(item);
}else{
inactive.push(item);
}
}
console.log(active, inactive);

If I'm understand you correctly, all you need to do is active.push(myData[i]) to push the reference into the array and do the same for inactive.

Instead of pushing a new object containing the active/inactive objects, just push the existing object itself.
var active = [];
var inactive = [];
for (var i = 0; i < myData.length; i++) {
if(myData[i].active) {
active.push(myData[i]);
} else {
inactive.push(myData[i]);
}
}

Related

Generating Entries with Same Name in JavaScript Object

I'm new to Javascript and I've done a little research but I can't seem to figure out how to generate multiple lists with same name keys but different values. I'm trying to generate code for an embed message which should look something like this:
{embed: {
color: 3447003,
title: "title",
description: "desc",
fields: [{
name: "header 1",
value: "text 1"
},
{
name: "header 2",
value: "text 2"
},
{
name: "header 3",
value: "text 3"
}
]
}
}
this is for generating a list of my commands in an embed automatically so I don't have to keep going back and edit it.
I'm mainly trying to get multiple of the "fields" with the "name" and "value" entries and also trying to add all the commands in a line for the "value".
Here's my code:
let currentCategory = "";
var embed = {
"title": "= __Command List__ =",
"description": `[Use ${message.settings.prefix}help <commandname> for details]`,
"color": 2563607,
fields : []
};
const sorted = myCommands.array().sort((p, c) => p.help.category > c.help.category ? 1 : p.help.name > c.help.name && p.help.category === c.help.category ? 1 : -1 );
sorted.forEach( c => {
const cat = c.help.category.toProperCase();
if (currentCategory !== cat) {
embed.fields = [{name : `${cat}`,value : ""}];
currentCategory = cat;
}
embed.fields[0].value += ` \`${c.help.name}\``;
});
console.log({embed});
message.channel.send({embed});
I used console.log({embed}); to print the code it generates in the console and this is what shows.
{ embed:
{ title: '= __Command List__ =',
description: '[Use y!help <commandname> for details]',
color: 2563607,
fields: [ [Object] ] } }
Ok I figured it out thanks to PM 77-1.
For anyone else who wants to know I basically set and index of -1 and made it add to the index while it looped for every new category.
let currentCategory = "";
let index = -1;
var embed = {
"title": "= __Command List__ =",
"description": `[Use ${message.settings.prefix}help <commandname> for details]`,
"color": 2563607,
fields : []
};
const sorted = myCommands.array().sort((p, c) => p.help.category > c.help.category ? 1 : p.help.name > c.help.name && p.help.category === c.help.category ? 1 : -1 );
sorted.forEach( c => {
const cat = c.help.category.toProperCase();
if (currentCategory !== cat) {
index = index + 1
embed.fields[index] = {name : `${cat}`,value : ""};
currentCategory = cat;
}
embed.fields[index].value += ` \`${c.help.name}\``;
});
console.log({embed});
message.channel.send({embed});

How can I remove duplicates in an array of object?

I have an array which looks like this :
var array =
[
{
key : { id : 1 , pack : "pack 1"},
values : [
{
item : { id : 1 , name : "item1"},
itemP : {id : 2 , name : "itemP12"}
},
{
item : { id : 4 , name : "item4"},
itemP : {id : 2 , name : "itemP12"}
},
]
}
]
I want to remove duplicate itemP so with a function it will look like this :
var array =
[
{
key : { id : 1 , pack : "pack 1"},
values : [
{
item : { id : 1 , name : "item1"},
itemP : {id : 2 , name : "itemP12"}
},
{
item : { id : 4 , name : "item4"},
itemP : null
},
]
}
]
When I try I always have errors. It is possible to do this?
Update
I try to do this :
console.log(array.map(pack =>
pack.values.map((item) => {
var test = JSON.stringify(item)
var set = new Set(test)
return Array.from(set).map((item)=> JSON.parse(item))
}
)
))
Unexpected end of JSON input
I also try something will filter but it doesn't work:
console.log(this.package.map(pack => pack.values.filter(
(value, index , array) => array.itemP.indexOf(value) === index
)))
Instead of mapping every key property, I suggest cloning the whole structure and setting the object value as null in the cloned one, avoiding unintentionally mutating the original structure.
function nullifyDupes(array) {
const clone = JSON.parse(JSON.stringify(array));
const seen = {};
clone.forEach(pack => {
pack.values.forEach(items => {
for (const item in items) {
const id = items[item].id;
if (seen[id]) items[item] = null;
else seen[id] = true;
}
});
});
return clone;
}
const originalArray = [{
key : { id : 1 , pack : "pack 1"},
values : [{
item : { id : 1 , name : "item1"},
itemP : {id : 2 , name : "itemP12"}
},
{
item : { id : 4 , name : "item4"},
itemP : {id : 2 , name : "itemP12"}
}]
}];
const mutatedArray = nullifyDupes(originalArray);
console.log(mutatedArray);
To achieve expected result, use below option of using map
Loop array using map
Use nameArr to check duplicate and assigning null value
Loop values array and check the name in nameArr using indexOf and assign null
var array = [
{
key : { id : 1 , pack : "pack 1"},
values : [
{
item : { id : 1 , name : "item1"},
itemP : {id : 2 , name : "itemP12"}
},
{
item : { id : 4 , name : "item4"},
itemP : {id : 2 , name : "itemP12"}
}
]
}
]
console.log(array.map(v => {
let nameArr = []
v.values = v.values.map(val => {
if(nameArr.indexOf(val.itemP.name) !== -1){
val.itemP.name = null
}else{
nameArr.push(val.itemP.name)
}
return val
})
return v
}))
You can use map and an object to check if its already exist. Like
var obj = {}
and loop over values
var values = [
{
item : { id : 1 , name : "item1"},
itemP : {id : 2 , name : "itemP12"}
},
{
item : { id : 4 , name : "item4"},
itemP : {id : 2 , name : "itemP12"}
}
]
values.map((v) => {
if(!obj[v.itemP.id + '-' + v.itemP.name]) {
obj[v.itemP.id + '-' + v.itemP.name] = true;
return v;
}
return { item : v.item }
})
You can map your array elements to array objects which don't include your duplicates using .map(). For each iteration of .map() you can again use .map() for your inner values array to convert it into an array of objects such that the duplicates are converted to null. Here I have kept a seen object which keeps track of the properties seen and their stringified values. By looping over all the properties in your object (using for...of), you can work out whether or not the key-value pair has been seen before by using the seen object.
The advantage of this approach is that it doesn't just work with one property (ie not just itemP), but it will work with any other duplicating key-value pairs.
See example below:
const array = [{key:{id:1,pack:"pack 1"},values:[{item:{id:1,name:"item1"},itemP:{id:2,name:"itemP12"}},{item:{id:4,name:"item4"},itemP:{id:2,name:"itemP12"}}]}];
const seen = {};
const res = array.map(obj => {
obj.values = obj.values.map(vobj => {
for (let p in vobj) {
vobj[p] = seen[p] === JSON.stringify(vobj[p]) ? null : vobj[p];
seen[p] = seen[p] || JSON.stringify(vobj[p]);
}
return vobj;
});
return obj;
});
console.log(res);
For an approach which just removed itemP from all object in accross your array you can use:
const array = [{key:{id:1,pack:"pack 1"},values:[{item:{id:1,name:"item1"},itemP:{id:2,name:"itemP12"}},{item:{id:4,name:"item4"},itemP:{id:2,name:"itemP12"}}]}];
let itemP = "";
const res = array.map(obj => {
obj.values = obj.values.map(vobj => {
vobj.itemP = itemP ? null : vobj.itemP;
if('itemP' in vobj) {
itemP = itemP || JSON.stringify(vobj.itemP);
}
return vobj;
});
return obj;
});
console.log(res);

How to append an object to an array based on the number of properties other than the specified properties?

For example , I have an array of objects like so :
[
{
"waterfallData.PopulationName":"Population 1",
"Deaths":-2333,
"Births":8786,
"open":0,
"close":6453
},
{
"waterfallData.PopulationName":"Population 2",
"Deaths":-1000,
"Births":5000,
"open":0,
"close":10453
},
{
"waterfallData.PopulationName":"Population 3",
"Deaths":-2000,
"Births":500,
"open":0,
"close":8953
}
]
I want to add two(does not have to be two,if there is a "Extra Births" then three) intermerdiate objects between each population like so
[
{
"waterfallData.PopulationName":"Population 1",
"Death":-2333,
"Births":8786,
"open":0,
"close":6453
},
{
"Deaths" : -1000,
"open" : 6453,
"close" : 5453
},
{
"Births" : 5000,
"open" : 5453,
"close : 10453
}
{
"waterfallData.PopulationName":"Population 2",
"Deaths":-1000,
"Births":5000,
"open":0,
"close":10453
},
{
"Deaths" : -2000,
"open" : 10453,
"close" : 8453
},
{
"Births" : 500,
"open" : 8453,
"close" : 8953
}
{
"waterfallData.PopulationName":"Population 3",
"Deaths":-2000,
"Births":500,
"open":0,
"close":8953
}
]
So as you can see I want to add objects based on the number of properties other than the waterfallData.PopulationName ,open and close properties. Then, I want to assign open and close properties on each object based on the next "Deaths" and "Births" values.
For example , Population 1 starts with 6453 then I add two objects with the 1st object taking the next "Deaths" value in Population 2 which is -1000 then I assign the open property to be from the previous close property of Population 1 and the close property to be calculated by adding the assigned open property to "Deaths"'s value. And same goes with the 2nd extra object where I assign the open property to be the close property of the previous object and the close property to be calculated by adding open with "Births"'s value.
How do I achieve this?
Crude.. but works
var newArr = [];
$x = [{
"waterfallData.PopulationName":"Population 1",
"Deaths":-2333,
"Births":8786,
"open":0,
"close":6453
},{
"waterfallData.PopulationName":"Population 2",
"Deaths":-1000,
"Births":5000,
"open":0,
"close":10453
},{
"waterfallData.PopulationName":"Population 3",
"Deaths":-2000,
"Births":500,
"open":0,
"close":8953
}];
$x.forEach((p,i)=>{
var current = $x[i]
newArr.push(current)
try {
var next = $x[i+1];
var start = current.open;
var end = current.close;
var states = Object.keys(current).sort().filter((k)=>{return (['waterfallData.PopulationName','open','close'].indexOf(k) < 0)})
for (var i=0;i<states.length;i++){
var state = states[i]
var tempObj = {}
tempObj[states[i]] = next[states[i]]
tempObj['open'] = end;
end += next[states[i]];
tempObj['close'] = end;
newArr.push(tempObj)
}
} catch (e) {
return false;
}
})
The code will look for all properties other than waterfallData.Popu..,open,close and treats them as states. If you have 10 properties, there will be 7 states excluding the above 3. Then the open and close values of these states are then calculated from the next element and pushed to new array newArr.
I'll give it a try, you can specify what keys you need to be extra data but the original data must have values for those keys. It'll create the extra items in the order that the keys are provided:
const data = [{"waterfallData.PopulationName":"Population 1","Deaths":-2333,"Births":8786,"open":0,"close":6453},{"waterfallData.PopulationName":"Population 2","Deaths":-1000,"Births":5000,"open":0,"close":10453},{"waterfallData.PopulationName":"Population 3","Deaths":-2000,"Births":500,"open":0,"close":8953}];
const zip = (arr1, arr2) =>
[...new Array(Math.max(arr1.length, arr2.length))]
.map((_, i) => i)
.map((i) => [arr1[i], arr2[i]]);
const extras = (keys) => ([current, next]) =>
keys.map((key) => [key, next[key]]).reduce(
([result, lastClose], [key, nextValue]) => [
result.concat({
[key]: nextValue,
open: lastClose,
close: nextValue + lastClose,
}),
nextValue + lastClose,
],
[[], current.close],
)[0];
const withExtras = (keys) => ([current, next]) =>
!next
? [current]
: [current].concat(extras(keys)([current, next]));
console.log(
zip(data, data.slice(1)) //having [[current,next],[current,next]...]
.map(withExtras(['Deaths', 'Births']))
.flatten(),
);
console.log(
'diffenrent order different result',
zip(data, data.slice(1))
.map(withExtras(['Births', 'Deaths']))
.flatten(),
);

Retrieve an object from a two dimensional array matching a specific parameter [duplicate]

This question already has answers here:
Find object by id in an array of JavaScript objects
(36 answers)
Closed 5 years ago.
So I have a 2d array containing multiple objects. Each object has multiple properties and methods. I would like to return only the objects methods and properties that have a matching id to what I pass it. in this case, the id is 1.
const blogData = [
{
title : "Title 1",
date : "2017-07-15",
id : 1
},
{
title : "Title 2",
data : "2017-07-16",
id : 2
}
];
for (let i = 0; i < blogData.length; i++) {
if (blogData[i].id === 1) {
console.log(`Post #${blogData[i].id} loaded`);
}
}
You can filter the array based on ID, and assuming you just have one hit, you can return the first (and only) item, or skip shift() and get an array of matches.
const blogData = [{
title: "Title 1",
date: "2017-07-15",
id: 1
},
{
title: "Title 2",
data: "2017-07-16",
id: 2
}
];
var result = blogData.filter( x => x.id === 1).shift();
console.log(result)
You can use a generic function that will work with any ID and any list.Something like:
const blogData = [
{
title : "Title 1",
date : "2017-07-15",
id : 1
},
{
title : "Title 2",
data : "2017-07-16",
id : 2
}
];
function getData(id, arr, callback){
$.each(arr, function(key, value){
if(value.id === id)
callback(value); //Just using a simple callback for console purposes
});
}
$(document).ready(function(){
getData(1, blogData, function(c){
console.log(c); //loggin the callback
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
In your case this is an array of objects and not a 2 dimentional array, so you can use Array.prototype.filter() method to filter only the object that has the id=1:
var res = blogData.filter(function(obj){
return obj.id === searchedId;
}).shift();
Demo:
const blogData = [
{
title : "Title 1",
date : "2017-07-15",
id : 1
},
{
title : "Title 2",
data : "2017-07-16",
id : 2
}
];
var searchedId = 1;
var res = blogData.filter(function(obj){
return obj.id === searchedId;
}).shift();
console.log(res);
And using your method with foor loop, you just need to return the right object if the condition is matched:
var result = {};
for (let i = 0; i < blogData.length; i++) {
if (blogData[i].id === 1) {
result = blogData[i]
}
}

Compare Multiple JSON Arrays

I have 3 arrays as displayed below. I have no control over the arrays.
groups_array = [ {
"group" : "Mobile Test Region",
"id" : "251"
}, {
"group" : "Mobile Demo Region",
"id" : "252"
} ]
locations_array = [ {
"location" : "M Testing",
"id" : "1376"
}, {
"location" : "Trade Show Machine",
"id" : "1403"
}, {
"location" : "M Trailer",
"id" : "1471"
}, {
"location" : "Test Los Angeles",
"id" : "1475"
} ]
pairs_array = [ {
"location_id" : "1376",
"group_id" : "251"
}, {
"location_id" : "1475",
"group_id" : "251"
}, {
"location_id" : "1403",
"group_id" : "252"
}, {
"location_id" : "1471",
"group_id" : "252"
} ]
Here is the code I used to loop through the pairs_array and retrieve the location_id's that correspond with the group id. Ti.API.info(pairs_array[s].location_id); outputs 2 location ID's based on the groupid given using e.rowData.groupid.
for (var s = 0; s < pairs_array.length; s++) {
if (e.rowData.groupid === pairs_array[s].group_id) {
Ti.API.info(pairs_array[s].location_id);
}
}
I am trying to compare the strings and retrieve the location names using the location_id's ive gotten from the IF statement. Should I just push the results into an array and loop through the location_array and the results and compare? If so, I'd like to see a good code snippet for that since the few times I tried I was not getting the expected output.
for (var s = 0; s < pairs_array.length; s++) {
if (e.rowData.groupid === pairs_array[s].group_id) {
Ti.API.info(pairs_array[s].location_id);
// find location name
for(var t = 0; t < locations_array.length; t++)
{
if(locations_array[t].id == pairs_array[s].location_id)
{
location_name = locations_array[t].location;
}
}
}
}

Categories