How to convert an object into an array in JavaScript? - javascript

When I console.log on a variable called "source" I get the following:
[Object {
name = "Yahoo", value = "yahoo"
},
Object {
name = "yahtzee", value = "yahtzee"
},
Object {
name = "Yakov Smirnoff", value = "yakov-smirnoff"
},
Object {
name = "Yarbrough", value = "yarbrough"
},
Object {
name = "yard sales", value = "yard-sales"
},
Object {
name = "yarmulke", value = "yarmulke"
},
Object {
name = "yawning", value = "yawning"
},
Object {
name = "Yeah Yeah Yeahs", value = "yeah-yeah-yeahs"
},
Object {
name = "Yeardly Smith", value = "yeardly-smith"
},
Object {
name = "YearOne", value = "yearone"
},
Object {
name = "Yeasayer", value = "yeasayer"
},
Object {
name = "yelle", value = "yelle"
},
Object {
name = "yelling", value = "yelling"
},
Object {
name = "yellowpages", value = "yellowpages"
},
Object {
name = "yellowstone", value = "yellowstone"
},
Object {
name = "yemen", value = "yemen"
},
Object {
name = "Yeoman", value = "yeoman"
},
Object {
name = "Yes Dear", value = "yes-dear"
},
Object {
name = "Yes Men", value = "yes-men"
},
Object {
name = "yeti", value = "yeti"
},
Object {
name = "yiddish", value = "yiddish"
},
Object {
name = "ymca", value = "ymca"
},
Object {
name = "yodeling", value = "yodeling"
},
Object {
name = "yoga", value = "yoga"
},
Object {
name = "yogurt", value = "yogurt"
},
Object {
name = "Yoko Ono", value = "yoko-ono"
},
Object {
name = "Yo-Landi Vi$$er", value = "yo-landi-vier"
},
Object {
name = "yo momma", value = "yo-momma"
},
Object {
name = "YONKERS", value = "yonkers"
},
Object {
name = "yosemite", value = "yosemite"
},
Object {
name = "yoshimoto", value = "yoshimoto"
},
Object {
name = "Yoshio Yoda", value = "yoshio-yoda"
},
Object {
name = "you got served", value = "you-got-served"
},
Object {
name = "YourDailyLaughz", value = "yourdailylaughz"
},
Object {
name = "yourfavorite", value = "yourfavorite"
},
Object {
name = "Yoursie Thomas", value = "yoursie-thomas"
},
Object {
name = "You Suck at Photoshop", value = "you-suck-at-photoshop"
},
Object {
name = "Youth in Revolt", value = "youth-in-revolt"
},
Object {
name = "Youtube Next Lab", value = "youtube-next-lab"
},
Object {
name = "YSAP", value = "ysap"
},
Object {
name = "yt3d:aspect=16:9", value = "yt3daspect169"
},
Object {
name = "yt3d:enable=true", value = "yt3denabletrue"
},
Object {
name = "yt3d:metadata=user", value = "yt3dmetadatauser"
},
Object {
name = "yt3d:swap=true", value = "yt3dswaptrue"
},
Object {
name = "y tu mama tambien", value = "y-tu-mama-tambien"
},
Object {
name = "YuGiOh", value = "yugioh"
},
Object {
name = "Yugo Koral", value = "yugo-koral"
},
Object {
name = "Yuri Baranovsky", value = "yuri-baranovsky"
},
Object {
name = "Yvan Attal", value = "yvan-attal"
},
Object {
name = "Yvette Nicole Brown", value = "yvette-nicole-brown"
},
Object {
name = "yvonne de carlo", value = "yvonne-de-carlo"
}]
If I stringify it first before console.logging it:
JSON.stringify(source);
I get:
[{
"name": "Yahoo",
"value": "yahoo"
}, {
"name": "yahtzee",
"value": "yahtzee"
}, {
"name": "Yakov Smirnoff",
"value": "yakov-smirnoff"
}, {
"name": "Yarbrough",
"value": "yarbrough"
}, {
"name": "yard sales",
"value": "yard-sales"
}, {
"name": "yarmulke",
"value": "yarmulke"
}, {
"name": "yawning",
"value": "yawning"
}, {
"name": "Yeah Yeah Yeahs",
"value": "yeah-yeah-yeahs"
}, {
"name": "Yeardly Smith",
"value": "yeardly-smith"
}, {
"name": "YearOne",
"value": "yearone"
}, {
"name": "Yeasayer",
"value": "yeasayer"
}, {
"name": "yelle",
"value": "yelle"
}, {
"name": "yelling",
"value": "yelling"
}, {
"name": "yellowpages",
"value": "yellowpages"
}, {
"name": "yellowstone",
"value": "yellowstone"
}, {
"name": "yemen",
"value": "yemen"
}, {
"name": "Yeoman",
"value": "yeoman"
}, {
"name": "Yes Dear",
"value": "yes-dear"
}, {
"name": "Yes Men",
"value": "yes-men"
}, {
"name": "yeti",
"value": "yeti"
}, {
"name": "yiddish",
"value": "yiddish"
}, {
"name": "ymca",
"value": "ymca"
}, {
"name": "yodeling",
"value": "yodeling"
}, {
"name": "yoga",
"value": "yoga"
}, {
"name": "yogurt",
"value": "yogurt"
}, {
"name": "Yoko Ono",
"value": "yoko-ono"
}, {
"name": "Yo-Landi Vi$$er",
"value": "yo-landi-vier"
}, {
"name": "yo momma",
"value": "yo-momma"
}, {
"name": "YONKERS",
"value": "yonkers"
}, {
"name": "yosemite",
"value": "yosemite"
}, {
"name": "yoshimoto",
"value": "yoshimoto"
}, {
"name": "Yoshio Yoda",
"value": "yoshio-yoda"
}, {
"name": "you got served",
"value": "you-got-served"
}, {
"name": "YourDailyLaughz",
"value": "yourdailylaughz"
}, {
"name": "yourfavorite",
"value": "yourfavorite"
}, {
"name": "Yoursie Thomas",
"value": "yoursie-thomas"
}, {
"name": "You Suck at Photoshop",
"value": "you-suck-at-photoshop"
}, {
"name": "Youth in Revolt",
"value": "youth-in-revolt"
}, {
"name": "Youtube Next Lab",
"value": "youtube-next-lab"
}, {
"name": "YSAP",
"value": "ysap"
}, {
"name": "yt3d:aspect=16:9",
"value": "yt3daspect169"
}, {
"name": "yt3d:enable=true",
"value": "yt3denabletrue"
}, {
"name": "yt3d:metadata=user",
"value": "yt3dmetadatauser"
}, {
"name": "yt3d:swap=true",
"value": "yt3dswaptrue"
}, {
"name": "y tu mama tambien",
"value": "y-tu-mama-tambien"
}, {
"name": "YuGiOh",
"value": "yugioh"
}, {
"name": "Yugo Koral",
"value": "yugo-koral"
}, {
"name": "Yuri Baranovsky",
"value": "yuri-baranovsky"
}, {
"name": "Yvan Attal",
"value": "yvan-attal"
}, {
"name": "Yvette Nicole Brown",
"value": "yvette-nicole-brown"
}, {
"name": "yvonne de carlo",
"value": "yvonne-de-carlo"
}]
Is there any way I can convert source into an array that looks like:
["Yahoo", "yahtzee", "Yakov Smirnoff", etc...]
Basically I just need the "name"s and not the "value"s, and I need them all in one array. How can this be done?

As an alternative to the other answers, you could use Array.prototype.map. Note, though, that it's fairly new and not available in older browsers -- for these, I recommend es5-shim.
var names = source.map(function(item) { return item.name });
Update: With ES6, it would look something like this:
const names = source.map(item => item.name)

Just use a simple for loop:
var arr = [];
for (var i = 0; i < objects.length; i++) {
arr.push(objects[i].name);
}

Update 06 July 2020
In ES6, there are three (3) variations to convert an Object to an Array as follows:
const MyObjects = { key1: 'value 1', key2: 'value 2', };
// Method 1: Converts the keys to Array
// --------------------------------------
Object.keys(MyObjects);
// ['key1', 'key2']
// Method 2 Converts the Values to Array
// --------------------------------------
Object.values(MyObjects);
// ['value 1', 'value 2']
// Method 3 Converts both Values and Keys
// --------------------------------------
Object.entries(MyObjects);
// [ ['key1', 'value 1'], ['key2', 'value 2'] ]
Converting an Array back to an Object can be done as follows:
const array = [ ['one', 1], ['two', 2], ];
Object.fromEntries(array);
// { one: 1, two: 2 }

Your outer structure is an array containing a bunch of object literals. Push the name property of each object literal onto a new array, via a simple for loop.
var outArray = [];
for (i=0; i<inArray.length; i++ {
outArray.push(inArray[i].name);
}
console.log(outArray);

var result = [];
for (var i in source)
result.push(source[i].name);

Related

How in JS to merge in one object two json objects where the ID of on object correspond on the same ID of the second object

My question relates to the fact I'm querying 2 different objects from DB and the result is in JSON. I need to merge them into one.
The 2 objects have in common this two key/value IRBId = ... and id = ... and they look as an example
OBJ 1
{
"data":{
"IRBs":{
"nodes":[
{
"id":"8",
"name":"Admin ",
},
{
"id":"9",
"name":"Again",
}
],
}
}
}
OBJ 2
{
"data":{
"informedConsentForms":{
"count":3,
"nodes":[
{
"id":"93",
...
"IRBId":"9",
},
{
"id":"92",
...
"IRBId":"8",
},
{
"id":"91",
...
"IRBId":"8",
}
],
}
},
As you will see above OBJ 2 and OBJ 1 corresponding with the same at IRBid and id.
What I need is to merge the two OBJ where IRBId OBJ 2 === id OBJ 1
The result I would expect after the merge is
OBJ merged
{
[{
"id":"93",
...
"IRBId":"9",
"irb": {
"name":"Again ",
...
}
},
{
"id":"92",
...
"IRBId":"8",
"irb": {
"name":"Admin ",
...
}
},
{
"id":"91",
...
"IRBId":"8",
"irb": {
"name":"Admin ",
...
}
],
},
I don't know how to make it looks like this.
Try using Array.reduce
Logic
Loop through second object data nodes
Find the matching nodes from object 1 data nodes.
Push to accumulator with required details. (I have added only the nodes that was mentioned in in Expected resut, you can add asmuch as you need.)
const obj1 = {
"data": {
"IRBs": {
"nodes": [
{
"id": "8",
"name": "Admin ",
},
{
"id": "9",
"name": "Again",
}
],
}
}
}
const obj2 = {
"data": {
"informedConsentForms": {
"count": 3,
"nodes": [
{
"id": "93",
"IRBId": "9",
},
{
"id": "92",
"IRBId": "8",
},
{
"id": "91",
"IRBId": "8",
}
],
}
},
};
const obj1List = obj1.data.IRBs.nodes;
const output = obj2.data.informedConsentForms.nodes.reduce((acc, curr) => {
const matchingNode = obj1List.find((item) => item.id === curr.IRBId);
if (matchingNode) {
acc.push({
id: curr.id,
IRBId: curr.IRBId,
irb: {
name: matchingNode.name
}
})
}
return acc;
}, []);
console.log(output);
You need to use the map function on the nodes in the first object to construct a new object that contains the second and first object's attributes.
const obj1 = {
"data": {
"IRBs": {
"nodes": [{
"id": "8",
"obj1": "one",
"name": "Admin ",
},
{
"id": "9",
"obj1": "two",
"name": "Again",
}
]
}
}
};
const obj2 = {
"data": {
"informedConsentForms": {
"count": 3,
"nodes": [{
"id": "93",
"obj2": "1",
"IRBId": "9",
},
{
"id": "92",
"obj2": "2",
"IRBId": "8",
},
{
"id": "91",
"obj2": "3",
"IRBId": "8",
}
],
}
}
};
const obj1Data = obj1.data.IRBs.nodes;
const obj2Data = obj2.data.informedConsentForms.nodes;
const res = obj2Data.map(item => {
const obj1Item = obj1Data.find(obj1Item => item.IRBId === obj1Item.id);
return obj1Item ? { ...item, "irb": { ...obj1Item}} : { ...item};
});
console.log(res);
i am using nested loop, try this one
const obj2 = {
"data":{
"informedConsentForms":{
"count":3,
"nodes":[
{
"id":"93",
"IRBId":"9",
},
{
"id":"92",
"IRBId":"8",
},
{
"id":"91",
"IRBId":"8",
}
],
}
},
}
const obj1 = {
"data":{
"IRBs":{
"nodes":[
{
"id":"8",
"name":"Admin ",
},
{
"id":"9",
"name":"Again",
}
],
}
}
}
const result = [];
const obj2Nodes = obj2.data.informedConsentForms.nodes;
for(let i = 0; i < obj2Nodes.length; i++) {
const obj1Nodes = obj1.data.IRBs.nodes
for(let j = 0; j < obj1Nodes.length; j++) {
if(obj2Nodes[i].IRBId === obj1Nodes[j].id) {
const {id, ...reObj1Nodes} = obj1Nodes[j];
result.push({
...obj2Nodes[i],
'irb': {
...reObj1Nodes
}
})
}
}
}
console.log(result)

Forming JSON with Key and Value if Key Exists

I have a JSON Structure something like:
[
{
"name":"angelinas"
},
{
"name":"besuto"
},
{
"name":"catch",
"cuisine":"Japanese"
},
{
"name":"center cut"
},
{
"name":"fedora"
},
{
"name":"Habanero",
"cuisine":"Mexican"
},
{
"name":"Indies"
},
{
"name":"new"
},
{
"name":"RazINN"
},
{
"name":"restaurantTestVenue779"
},
{
"name":"restaurantTestVenue9703"
},
{
"name":"Salsa ",
"cuisine":"Mexican"
},
{
"name":"Sushi Place",
"cuisine":"Japanese"
},
{
"name":"The Ashoka"
},
{
"name":"The Poboys"
},
{
"name":"the shogun"
},
{
"name":"vinyard view"
}
]
Using the JSON above i want to identify whether a cuisine is assosiated to restaurant. If yes, I want to build a JSON Structure something like:
[
{
"Mexican":{
"venueNames":[
"Habanero",
"Salsa"
]
}
},
{
"Japanese":{
"venueNames":[
"Sushi Place",
"catch"
]
}
}
]
Have tried to build the JSON using a for loop and .hasProperty but not much of a success.
Here is what you can do!
First iterate through the data and use the method "hasOwnProperty" to check if the cuisine exists and if it does then check if your cuisines object has that cuisine and if does then add it to it.
const data = [{
"name": "angelinas"
},
{
"name": "besuto"
},
{
"name": "catch",
"cuisine": "Japanese"
},
{
"name": "center cut"
},
{
"name": "fedora"
},
{
"name": "Habanero",
"cuisine": "Mexican"
},
{
"name": "Indies"
},
{
"name": "new"
},
{
"name": "RazINN"
},
{
"name": "restaurantTestVenue779"
},
{
"name": "restaurantTestVenue9703"
},
{
"name": "Salsa ",
"cuisine": "Mexican"
},
{
"name": "Sushi Place",
"cuisine": "Japanese"
},
{
"name": "The Ashoka"
},
{
"name": "The Poboys"
},
{
"name": "the shogun"
},
{
"name": "vinyard view"
}
]
let cuisines = {};
for (const resturant of data) {
if (resturant.hasOwnProperty('cuisine')) {
if (cuisines.hasOwnProperty(resturant.cuisine)) {
cuisines[resturant.cuisine].venueNames.push(resturant.name);
} else {
cuisines[resturant.cuisine] = {
venueNames: [resturant.name]
};
}
}
}
You can use in one loop below.
data.forEach(function(item) {
// if item has cuisine and cuisine not exist in new array
if(item["cuisine"] != null && typeof newArr.find(v => v[item.cuisine] != null) == 'undefined') {
// create new object with structure
let obj = {};
obj[item.cuisine] = {
"venueNames":[item.name]
};
newArr.push(obj);
}
else {
// else find existing cuisine and add new venue
let obj = newArr.find(v => v.hasOwnProperty(item.cuisine));
if(typeof obj != 'undefined') {
obj[item.cuisine].venueNames.push(item.name);
}
}
});
JSFIDDLE
It's a simple reduction of the array. If the restaurant has a defined cuisine, check if the result already has this cuisine defined. If not, create an object for it where you can push the restaurant name to.
const restaurants = [
{
"name":"angelinas"
},
{
"name":"besuto"
},
{
"name":"catch",
"cuisine":"Japanese"
},
{
"name":"center cut"
},
{
"name":"fedora"
},
{
"name":"Habanero",
"cuisine":"Mexican"
},
{
"name":"Indies"
},
{
"name":"new"
},
{
"name":"RazINN"
},
{
"name":"restaurantTestVenue779"
},
{
"name":"restaurantTestVenue9703"
},
{
"name":"Salsa ",
"cuisine":"Mexican"
},
{
"name":"Sushi Place",
"cuisine":"Japanese"
},
{
"name":"The Ashoka"
},
{
"name":"The Poboys"
},
{
"name":"the shogun"
},
{
"name":"vinyard view"
}
];
const cuisines = restaurants.reduce((result, restaurant ) => {
if ( restaurant.hasOwnProperty( 'cuisine' )) {
const { cuisine } = restaurant;
if ( !result.hasOwnProperty( cuisine )) {
result[ cuisine ] = {
venueNames: []
};
}
result[ cuisine ].venueNames.push( restaurant.name );
}
return result;
}, {});
console.log( cuisines );
In my personal opinion, I would use a slightly different structure though. If we represent collections with objects that are always the same, we can simplify most transformations. This is less efficient that doing everything in one loop, but the code used to create the transformation is almost readable english:
const restaurants = [
{ "name": "angelinas", "cuisine": null },
{ "name": "besuto", "cuisine": null },
{ "name": "catch", "cuisine": "japanese" },
{ "name": "center cut", "cuisine": null },
{ "name": "fedora", "cuisine": null },
{ "name": "habanero", "cuisine": "mexican" },
{ "name": "Indies", "cuisine": null },
{ "name": "new", "cuisine": null },
{ "name": "RazINN", "cuisine": null },
{ "name": "restaurantTestVenue779", "cuisine": null },
{ "name": "restaurantTestVenue9703", "cuisine": null },
{ "name": "Salsa ", "cuisine": "mexican" },
{ "name": "Sushi Place", "cuisine": "japanese" },
{ "name": "The Ashoka", "cuisine": null },
{ "name": "The Poboys", "cuisine": null },
{ "name": "the shogun", "cuisine": null },
{ "name": "vinyard view", "cuisine": null }
];
const create_cuisine = name => ({ name, "venues": [] });
const unique = () => {
const seen = {};
return item => {
const json = JSON.stringify( item );
return seen.hasOwnProperty( json )
? false
: ( seen[ json ] = true );
};
};
// Filter away all the restaurants without a cuisine value.
const restaurants_with_cuisine = restaurants.filter( restaurant => restaurant.cuisine );
const cuisines = restaurants_with_cuisine
// Extract the cuisine anmes from the restaurants.
.map( restaurant => restaurant.cuisine )
// Filter aways all the duplicates.
.filter( unique() )
// Create a new cuisine object.
.map( cuisine_name => create_cuisine( cuisine_name ));
// Finally add all the restaurant names to the right cuisine.
restaurants_with_cuisine.forEach( restaurant => cuisines.find( cuisine => cuisine.name === restaurant.cuisine ).venues.push( restaurant.name ));
console.log( cuisines );
Using a few es6 features, we can generate this list with Set, map and filter.
We will first map a list of cuisines, and remove invalid ones such as undefined. With that we will use a Set to create a unique list of cuisines.
Next we will take that list and map it again to return the final object, by filtering the original object where the cuisine matches the current iteration. Finally we map the filtered results to return just the name to the venueNames object.
Our result will look like this:
function getItems(places) {
// Get a unique list of cuisines
return [...new Set(places.map(p => p.cuisine).filter(c => c))]
// Build the result
.map(c => {
return {
[c]: {
// Get a list of cuisines that match the current cuisine
venueNames: places.filter(p => p.cuisine == c).map(c => c.name)
}
}
})
}
const places = [
{"name": "angelinas"},
{"name": "besuto"},
{"name": "catch","cuisine": "Japanese"},
{"name": "center cut"},
{"name": "fedora"},
{"name": "Habanero","cuisine": "Mexican"},
{"name": "Indies"},
{"name": "new"},
{"name": "RazINN"},
{"name": "restaurantTestVenue779"},
{"name": "restaurantTestVenue9703"},
{"name": "Salsa ","cuisine": "Mexican"},
{"name": "Sushi Place","cuisine": "Japanese"},
{"name": "The Ashoka"},
{"name": "The Poboys"},
{"name": "the shogun"},
{"name": "vinyard view"}
]
console.log(getItems(places))

Group and count values in an array

I have an array with objects, like the following.
b = {
"issues": [{
"fields": {
"status": {
"id": "200",
"name": "Backlog"
}
}
}, {
"fields": {
"status": {
"id": "202",
"name": "close"
}
}
}, {
"fields": {
"status": {
"id": "201",
"name": "close"
}
}
}]
};
I want to count how many issues have status close, and how many have backlog. I'd like to save the count in a new array as follows.
a = [
{Name: 'Backlog', count: 1},
{Name: 'close', count: 2}
];
I have tried the following.
b.issues.forEach(function(i) {
var statusName = i.fields.status.name;
if (statusName in a.Name) {
a.count = +1;
} else {
a.push({
Name: statusName,
count: 1
});
}
});
That however doesn't seem to be working. How should I implement this?
This is a perfect opportunity to use Array#reduce. That function will take a function that is applied to all elements of the array in order and can be used to accumulate a value. We can use it to accumulate an object with the various counts in it.
To make things easy, we track the counts in an object as simply {name: count, otherName: otherCount}. For every element, we check if we already have an entry for name. If not, create one with count 0. Otherwise, increment the count. After the reduce, we can map the array of keys, stored as keys of the object, to be in the format described in the question. See below.
var b = {
"issues": [{
"fields": {
"status": {
"id": "200",
"name": "Backlog"
}
}
}, {
"fields": {
"status": {
"id": "202",
"name": "close"
}
}
}, {
"fields": {
"status": {
"id": "201",
"name": "close"
}
}
}]
};
var counts = b.issues.reduce((p, c) => {
var name = c.fields.status.name;
if (!p.hasOwnProperty(name)) {
p[name] = 0;
}
p[name]++;
return p;
}, {});
console.log(counts);
var countsExtended = Object.keys(counts).map(k => {
return {name: k, count: counts[k]}; });
console.log(countsExtended);
.as-console-wrapper {
max-height: 100% !important;
}
Notes.
Array#reduce does not modify the original array.
You can easily modify the function passed to reduce to for example not distinguish between Backlog and backlog by changing
var name = c.fields.status.name;
into
var name = c.fields.status.name.toLowerCase();
for example. More advanced functionality can also easily be implemented.
Using ES6 Arrow functions you can do it with minimum syntax
var b = {
"issues": [{
"fields": {
"status": {
"id": "200",
"name": "Backlog"
}
}
}, {
"fields": {
"status": {
"id": "202",
"name": "close"
}
}
}, {
"fields": {
"status": {
"id": "201",
"name": "close"
}
}
}]
};
var countOfBackLog = b.issues.filter(x => {
return x.fields.status.name === "Backlog"
}).length
var countOfClose = b.issues.filter(x => {
return x.fields.status.name === "close"
}).length
a =[{Name: 'Backlog', count : countOfBackLog}, {Name: 'close', count : countOfClose}]
More about arrow functions here
You can write like this. It is dynamic.
var a = {};
for(var key in b["issues"]){
if(!a.hasOwnProperty(b["issues"][key].fields.status.name)){
a[b["issues"][key].fields.status.name] = 1;
}else{
a[b["issues"][key].fields.status.name] = a[b["issues"][key].fields.status.name]+1;
}
}
var c = [];
for(var key1 in a){
c.push({
name : key1,
count : a[key1]
});
}
Something like this should do the trick. Simply iterate over your data, keep 2 counters with the number of each type of issue, and create the data format you want in the end. Try it live on jsfiddle.
var b = {
"issues": [{
"fields": {
"status": {
"id": "200",
"name": "Backlog"
}
}
}, {
"fields": {
"status": {
"id": "202",
"name": "close"
}
}
}, {
"fields": {
"status": {
"id": "201",
"name": "close"
}
}
}]
};
var data = [];
for(var issue of b.issues){
var entryFound = false;
var tempObj = {
name: issue.fields.status.name,
count: 1
};
for(var item of data){
if(item.name === tempObj.name){
item.count++;
entryFound = true;
break;
}
}
if(!entryFound){
data.push(tempObj);
}
}
console.log(data);

How to return object based on value in nested array? (Javascript)

I am trying to return all objects that have a specific 'id' in the nested array. In the sample data, I'd like to return all person objects with hobbies id of 2 (hiking).
The other question addresses the problem of finding all values in an array based on an object value.
This question differs from the previous because I need to return all objects based on a value inside of a nested array.
[
{
"id":111222,
"name":"Faye",
"age":27,
"hobbies":[
{
"id":2,
"name":"hiking"
},
{
"id":3,
"name":"eating"
}
]
},
{
"id":223456789001,
"name":"Bobby",
"age":35,
"hobbies":[
{
"id":2,
"name":"hiking"
},
{
"id":4,
"name":"online gaming"
}
]
}
]
function hasHobby(person, hobbyId) {
return person.hobbies.some(function(hobby) {
return hobby.id === hobbyId;
});
}
function filterByHobby(people, hobbyId) {
return people.filter(function(person) {
return hasHobby(person, hobbyId);
});
}
If you wanna use the new cool ES6 syntax:
function filterByHobby(people, hobbyId) {
return people.filter(
person => person.hobbies.some(
hobby => hobby.id === hobbyId
)
);
}
var arr = [
{
"id":111222,
"name":"Faye",
"age":27,
"hobbies":[
{
"id":2,
"name":"hiking"
},
{
"id":3,
"name":"eating"
}
]
},
{
"id":223456789001,
"name":"Bobby",
"age":35,
"hobbies":[
{
"id":2,
"name":"hiking"
},
{
"id":4,
"name":"online gaming"
}
]
}
];
arr.filter(function(obj) {
var hobbies = obj.hobbies;
var x = hobbies.filter(function(hob) {
if (hob.id == "2") return true;
});
if (x.length > 0) return true;
});
Try this, I think its solve your proble:
var arr = [{
"id": 111222,
"name": "Faye",
"age": 27,
"hobbies": [{
"id": 2,
"name": "hiking"
}, {
"id": 3,
"name": "eating"
}]
}, {
"id": 223456789001,
"name": "Bobby",
"age": 35,
"hobbies": [{
"id": 2,
"name": "hiking"
}, {
"id": 4,
"name": "online gaming"
}]
}];
var x = arr.filter(function(el) {
var rnel = el.hobbies.filter(function(nel) {
return nel.id == 2;
});
return rnel.length > 0 ? true :false;
});
alert(x.length);

How to combine multiple key values in JSON object?

I have this sample JSON object
var sample = [{
"label": "one",
"value": 1
}, {
"label": "two",
"value": 2
}, {
"label": "three",
"value": 3
}, {
"label": "four",
"value": 4
}, {
"label": "five",
"value": 5
}];
I want to change it some thing like this
var sample = [{
"label": "one",
"value": 1,
"newKeyValue": "one|1"
}, {
"label": "two",
"value": 2,
"newKeyValue": "two|2"
}, {
"label": "three",
"value": 3,
"newKeyValue": "three|3"
},
...
];
It should combine both key values and return new key value combining both.
JSON is coming dynamically key label and value are not static it can be anything. For example [{"name":"srinivas","lastname":"pai"}]
You can use map like this :
EDIT
For handling generic keys you can use
Object.keys(d)[0] for first key
Object.keys(d)[1] for second key
var sample = [
{
"label":"one",
"value":1
},
{
"label":"two",
"value":2
},
{
"label":"three",
"value":3
},
{
"label":"four",
"value":4
},
{
"label":"five",
"value":5
}
];
var data = sample.map(function(d){
return {label: Object.keys(d)[0], value: Object.keys(d)[1], newKeyValue: Object.keys(d)[0] +"|" + Object.keys(d)[1]}
})
console.log(data)
Hope this helps!
You can use Array#map(), Object.keys(), and Array#join().
In ES6, you can use Arrow functions.
sample = sample.map(obj => {
var keys = Object.keys(obj);
obj.newKeyValue = keys.map(key => obj[key]).join('|');
return obj;
});
var sample = [{
"label": "one",
"value": 1
}, {
"name": "two",
"age": 2
}, {
"five": "three",
"six": 3
}, {
"company": "four",
"organization": 4
}, {
"label": "five",
"value": 5
}];
sample = sample.map(function (x) {
var keys = Object.keys(x);
x.newKeyValue = keys.map(key => x[key]).join('|');
return x;
});
console.log(sample);
document.body.innerHTML = '<pre>' + JSON.stringify(sample, 0, 4) + '</pre>';
In ES5, you can use the same code with anonymous functions
sample = sample.map(function (obj) {
var keys = Object.keys(obj);
obj.newKeyValue = keys.map(function (key) {
return obj[key]
}).join('|');
return obj;
});
Limitations due to dynamic keys:
The order of the keys in object cannot be maintained
This will join all the available keys in the object (in case if you just want to join fewer)
var sample = [
{
"label":"one",
"value":1
},
{
"label":"two",
"value":2,
"optionalValue":2
},
{
"label":"three",
"value":3,
"remarks":"free text"
},
{
"label":"four",
"value":4
},
{
"label":"five",
"value":5
}
];
for (var key in sample) {
var newValue = [];
for (var piece in sample[key]){
newValue.push(sample[key][piece])
}
sample[key]["newKeyValue"] = newValue.join('|');
}
$('pre').html(JSON.stringify(sample,null,4));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre></pre>
You can use Array.prototype.forEach() for in situ changes.
The forEach() method executes a provided function once per array element.
Edit: with dynamic keys, stored in an array, because of the order.
var sample = [{ "label": "one", "value": 1 }, { "label": "two", "value": 2 }, { "label": "three", "value": 3 }, { "label": "four", "value": 4 }, { "label": "five", "value": 5 }];
sample.forEach(function (a) {
a.newKeyValue = ['label', 'value'].map(function (k) { return a[k]; }).join('|');
});
document.write('<pre>' + JSON.stringify(sample, 0, 4) + '</pre>');
If more element are their then use $.extend
var sample = [
{
"label":"one",
"value":1
},
{
"label":"two",
"value":2
},
{
"label":"three",
"value":3
},
{
"label":"four",
"value":4
},
{
"label":"five",
"value":5
}
];
$(sample).each(function(i,item){
var keyes = Object.keys(item);
sample[i] = $.extend(item,{newKeyValue: item[keyes[0]] +"|" +item[keyes[1]]});
});
console.log(sample)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
$.extend also helpful when you are having more objects already and you want to merge both
eg.
var base = {
"label":"one",
"value":1
}
and you want to add more objects
var extra = {
"new1":"value1",
"new2":"value2",
"new3":"value3",
"new4":"value4",
}
then it will be done by
$.extend(base,extra);
Output:
{
"label":"one",
"value":1,
"new1":"value1",
"new2":"value2",
"new3":"value3",
"new4":"value4",
}
var sample = [{"name":"srinivas","lastname":"pai"}];
sample.map(function(item) {
item.newKeyValue = Object.getOwnPropertyNames(item).map(function(d) {return item[d];}).join("|");
})
console.log(sample);

Categories

Resources