How to access multi-dimensional arrays (like this)? - javascript

I have an array and I'm not sure how to access certain keys. What I'm trying to accomplish is simply target certain keys/values in the array. Here's a sample of my array.
var jobs = [
{
// hunting
name: 'Hunting',
available: [
{
name: 'Housemate',
description: 'You stick around the cabin of the hunters. You are the lowest class of the hunters.',
salary: 10
},
{
name: 'Fetcher',
description: 'You are the fetcher of the clan. You gather leather, resources, and skin leather.',
salary: 15
},
{
name: 'Hunter',
description: 'You are a basic hunter of the clan. You hunt for food, meat, and leather.',
salary: 25
},
{
name: 'Elder',
description: 'You are a elder of the clan. You are respected among many, and may ask hunters for arrons.',
salary: 0
}
],
// construction
name: 'Construction',
available: [
{
name: 'Builder',
description: 'You are a builder. You are the lowest class of the construction tier.',
salary: 45
},
{
name: 'Driver',
description: 'You are a driver. You do the fetching and gathering of resources.',
salary: 55
},
{
name: 'Engineer',
description: 'You are a engineer. You do the wiring and electrical work in the construction.',
salary: 65
},
{
name: 'Overseer',
description: 'You are the overseer. You watch over the construction and give orders.',
salary: 80
}
],
}
];
Now keep in mind that I have multiple arrays in one array. Here I try to access the Hunter job category, the Fetcher job, and the construction Engineer salary.
alert(jobs.'Hunting'); // gives 'missing name after . operator' error
alert(jobs.name[0]); // gives 'name is not defined' error
alert(jobs.available.'Fetcher'); //same error as number 1
alert(jobs.available.salary[0]) // gives available is not defined error
How can I access those variables?

Your array of objects is malformed
Your original array contained a single item: one object which had the name and available properties defined twice.
I suspect you want your array to contain two items: two objects, each with a name and available property.
It should be this:
var jobs = [
{
// hunting
name: 'Hunting',
available: [
{
name: 'Housemate',
description: 'You stick around the cabin of the hunters. You are the lowest class of the hunters.',
salary: 10
}, {
name: 'Fetcher',
description: 'You are the fetcher of the clan. You gather leather, resources, and skin leather.',
salary: 15
}, {
name: 'Hunter',
description: 'You are a basic hunter of the clan. You hunt for food, meat, and leather.',
salary: 25
}, {
name: 'Elder',
description: 'You are a elder of the clan. You are respected among many, and may ask hunters for arrons.',
salary: 0
}
]
}, {
// construction
name: 'Construction',
available: [
{
name: 'Builder',
description: 'You are a builder. You are the lowest class of the construction tier.',
salary: 45
}, {
name: 'Driver',
description: 'You are a driver. You do the fetching and gathering of resources.',
salary: 55
}, {
name: 'Engineer',
description: 'You are a engineer. You do the wiring and electrical work in the construction.',
salary: 65
}, {
name: 'Overseer',
description: 'You are the overseer. You watch over the construction and give orders.',
salary: 80
}
],
}
];
Accessing items in the array
alert(jobs[0].name); // Returns 'Hunting'
alert(jobs[0].available[1].name); // Returns 'Fetcher'
alert(jobs[0].available[3].salary); // Returns '0'
Why don't the following examples work?
You can't use a string in dot notation:
alert(jobs.'Hunting');
alert(jobs.available.'Fetcher');
You cannot have a string after the dot. You should have a property name as in object.name, but you first need to define by its index which item in the array you're targeting as in array[i].name.
But even if you changed it to…
alert(jobs[0].Hunting); // OR
alert(jobs[0]['Hunting']);
…it would fail because there is no object with a property name of 'Hunting'.
Square brackets are misplaced:
alert(jobs.name[0]);
alert(jobs.available.salary[0]);
The above examples don't work because you are passing an index inside square brackets after your property name, where they should be placed after the array name. For example:
alert(jobs[0].name);
alert(jobs[0].available[0].salary);
Accessing objects in array by key/value
It looks like you're attempting to access the object's in the array by the value from one of its properties.
For example, above it seems you want to get the object whose property of name has a value of 'Hunting', which cannot be done directly.
You would need to create a function or use a library that provides a function for this, such as Underscore's _.find.
Example of using _.find to get an object by key/value:
var hunting = _.find(jobs, function(obj) {
return obj.name === 'Hunting';
});
View the above examples in JSFiddle

I took the liberty of fixing a syntax error in you example. As you can see in the comments, there were close/opening braces missing between Hunter and Construction.
}]},
// construction
{name: 'Construction',
You will need to use the index notation to get at the different elements in the array.
This will return the Hunter object. From there you can access the individual elements (either name or available).
console.log(jobs[0]);
This will give you the name of the first object's name property.
console.log(jobs[0].name);
This will return the first object under available.
console.log(jobs[0].available[0]);
This will return the name property from the first object under available.
console.log(jobs[0].available[0].name);
Here is a fiddle I created

You didn't build your object correctly, do this :
var jobs = {
// New child object create only for Hunting
hunting: {
// hunting
name: 'Hunting', // optional
available: [
{
name: 'Housemate',
description: 'You stick around the cabin of the hunters. You are the lowest class of the hunters.',
salary: 10
},
{
name: 'Fetcher',
description: 'You are the fetcher of the clan. You gather leather, resources, and skin leather.',
salary: 15
},
{
name: 'Hunter',
description: 'You are a basic hunter of the clan. You hunt for food, meat, and leather.',
salary: 25
},
{
name: 'Elder',
description: 'You are a elder of the clan. You are respected among many, and may ask hunters for arrons.',
salary: 0
}
]
},
// Other section, this time for Construction
construction : {
// construction
name: 'Construction', // Optional too
available: [
{
name: 'Builder',
description: 'You are a builder. You are the lowest class of the construction tier.',
salary: 45
},
{
name: 'Driver',
description: 'You are a driver. You do the fetching and gathering of resources.',
salary: 55
},
{
name: 'Engineer',
description: 'You are a engineer. You do the wiring and electrical work in the construction.',
salary: 65
},
{
name: 'Overseer',
description: 'You are the overseer. You watch over the construction and give orders.',
salary: 80
}
],
}
};
Now you can do :
var construction_jobs = jobs.construction.available;
If you absolutely want keep your array on first dimention you can do it :
var jobs = [
{
// hunting
name: 'Hunting',
available: [ /* objects... */ ]
},
{
// construction
name: 'Construction',
available: [ /* objects... */ ]
}
];
And use lodash lib to get data :
var job = _.findWhere(jobs, {name: 'Hunting'});
To understand, check your console log display on this codepen : http://codepen.io/ArthyFiciel/pen/waGxrm

Related

How to reduce/concat objects based on some other value in javascript

I am wondering what js functions can be used in the following case to get some array values together.
Here I want to concatenate the description values if the date value is null.
var incomes = [ { date: '05/03', description: '1st Description on 05/03', amount: '399.49' },
{ date: null, description: '1st Description continued on 05/03', amount: null },
{ date: null, description: '1st Description continued on 05/03', amount: null },
{ date: '05/03', description: '2nd Description on 05/03', amount: '269.85' },
{ date: null, description: '2nd Description continued on 05/03', amount: null },
{ date: null, description: '2nd Description continued on 05/03', amount: null }];
The result should look like this:
var results = [ { date: '05/03',
description: '1st Description on 05/03, 1st Description continued on 05/03, 1st Description continued on 05/03',
amount: '399.49' },
{ date: '05/03',
description: '2nd Description on 05/03, 2nd Description continued on 05/03, 2nd Description continued on 05/03',
amount: '269.85' }];
I think that we can use the usual loops, conditions, etc. But are there any handy method to solve this?
This really isn't a good use case for reduce/concat types of operations. Reduce is supposed to be given a pure function that only relies on its parameters and doesn't mutate any values. You're trying to produce an array, which would either involve creating the array and then mutating it (adding values), or creating copies of the array (via concat), like this:
const results = incomes.reduce((agg, v) =>
v.date
? agg.concat([v])
: agg.slice(0, -1)
.concat([{
...agg.slice(-1)[0],
description: `${agg.slice(-1)[0].description}, ${v.description}`}]),
[])
As you can see, there's a lot of duplicative sliceing and concating going on here, which is wasteful from a performance perspective. Perhaps more importantly, it's hard to reason with and hard to debug. I'd probably stick with using a for loop that tracks state and pushes to an array instead.
let results = [];
for (let v of incomes) {
if (v.date) {
results.push({...v});
} else {
results[results.length - 1].description += ", " + v.description;
}
}

extract properties from array of objects and store in another array of objects

i have an array of objects that is coming from server.
data:[
{
// values
}
]
below is one object element of that array.
0:
assignedTo:{
name: "Shokat iqbal"
},
category:{
name: "Fan"
},
complainer:{
name: "Testt"
},
details: "Makk Amjum and my name is yeh and i amthose who is ur father"
location: "Room number 87 blockasdas jknaksdnkaj knasdkan kasndka nasdkas"
status: "in-progress"
title: "My fan is damaged"
_id: "5cade948e0b7ce30c8ef2f05"
i want to extract some of its properties like
Assignee: assignedTo.name, category: Category.name, Complainer:complainer.name
and want to make another array of objects which will look like this.
[
{
Assignee: assignedTo.name,
Complainer: complainer.name,
Category: category.name,
title: title,
location: location,
details: details
}
]
please help me how to do this?
Welcome to SO. It's always good to try and show, or talk about some of the solutions that you have tried and where they failed. The community is great but they also appreciate people trying.
Array.map will do the trick for you
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
const formattedData = data.map(record => ({
Assignee: record.assignedTo.name,
Complainer: record.complainer.name,
Category: record.category.name,
title: record.title,
location: record.location,
details: record.details,
}));

Accessing infinite nested children object

Wanted to know how can we access infinitely nested object in JS?
Consider this example given to be my interviewer
You have an object with a Parent and infinitely nested children
[
{
name: "Jack",
age: "98" ,
profession: "doctor
children: [
{
name: "Varun",
age: "80"
profession: "scientist"
children: [
{
name: "Ishan"
age: "62",
profession: "teacher
children: [{....
.....
.....[{
name: "Rahul",
age: "23",
profession: "engineer"
children: [{
.....
I need to find the name corresponding where profession is "engineer" and how deep that given object is nested.
Note: Number of children to be considered here is infinite.
Question: Can someone help me in figuring out how I can do it with recursion and without recursion
update: He gave me a hint to use divide and conquer
Update: Based on the solution by Bary, I tried something like this
let infiniteArray = [
{
name: "Jack",
age: "98" ,
profession: "doctor",
children: [
{
name: "Varun",
age: "80",
profession: "scientist",
children: [
{
name: "Ishan",
age: "62",
profession: "teacher"
}
]
}
]
}
]
function isTheItem(item) {
if (item["profession"] === "teacher") return item
return false
}
function walk(collection) {
return collection.find(item => isTheItem(item) || walk(item.children));
}
But when I console.log it, i.e console.log(walk(infiniteArray)), it is logging the entire infiniteArray and I understand why but I went it to return just the name corresponding to profession. Any help on how I can achieve it?
name: "Ishan",
age: "62",
profession: "teacher"
}
There's two directions walking through your collection
* sibling
* nested
so you can iterate this sibling items with regular array iterator and recursively walk through the children of each item.
function isTheItem(item) {
return ...;
}
function walk(collection) {
return collection.find(item => isTheItem(item) || walk(item.children));
}
Divide and conquer algorithms usually have more to do with sorting values in an array (during an interview process). If you were sorting by age or something, I could see that being a hint. But there's no way to really divide and conquer when searching for a key value pair of an infinite number of nested objects. You have to search through n number of values until you find the result. Any dividing of the object doesn't necessarily improve efficiency with a random key value pair stored that you want to find.
More experienced devs correct me if I'm wrong here
Barry Gane has a good start to the code you would write for the actual application of this.

Can I set value of an object by accessing other values in this object?

I am new in React.js, I am designing a little game.
When I am setting the life value, I want to use the value of job, can I do it in React.js?
Here is part of my code:
this.setState({
players:[
{
id:uuid.v4(),
name: "A",
job: "Wizard",
life: this.getRandHealth("Wizard")
}, {
id:uuid.v4(),
name: "B",
job: "Witch",
life: this.getRandHealth("Witch")
}]});
I want directly access job instead of signing them manually. Can I do it?
A solution is to define the players list without the life and then use .map() to add it:
var list = [{
id: uuid.v4(),
name: "A",
job: "Wizard",
}, {
id: uuid.v4(),
name: "B",
job: "Witch",
}];
this.setState({
players: list.map(function(obj) {
return {
id: obj.id,
name: obj.name,
job: obj.job,
life: this.getRandHealth(obj.job)
};
}, this);
});
If the id is always uuid.v4() then you can move that into the map as well and reduce the repetition further.

How to access a specific index of an array in node.js

I want to get only the AID from the solution now i am getting. I tried rows[0] but was not successful.
Code:
console.log('The solution is: ', rows);
Output:
The solution is:
[ { AID: 6520,
DID: 113071,
TITLE: 'First Knight',
DATE: '7/7/1995',
SCORE: 89 } ]
Use rows[0]["AID"] to access the AID property.
Let's understand your overall data structure here:
var rows = [
{
AID: 6520,
DID: 113071,
TITLE: 'First Knight',
DATE: '7/7/1995',
SCORE: 89
}
];
The variable rows is an array of objects. Thus rows[n] gets you a specified object in that array and therefore rows[0] is the first object in the array which would be:
{
AID: 6520,
DID: 113071,
TITLE: 'First Knight',
DATE: '7/7/1995',
SCORE: 89
}
So, now you want to access the AID property in that object so you can just do:
rows[0].AID
And, here's a working snippet demo:
var rows = [
{
AID: 6520,
DID: 113071,
TITLE: 'First Knight',
DATE: '7/7/1995',
SCORE: 89
}
];
document.write(rows[0].AID);

Categories

Resources