Exploring possessions

Having created a simple function to retrieve certain values from an array that contains multiple nested objects, I am facing a dilemma with my loops.

My query pertains to the necessity of looping through the 3 objects before accessing their values. While I understand the need for initially looping through the entire array, I am puzzled as to why a separate loop is required for each object.

Instead of running two loops, can't I use the following code snippet to access the desired value:

animalNoises[i][animal][country]

Unfortunately, this line of code returns 'undefined' for me. Could this issue be related to the structure of the 3 animal objects?

I appreciate any assistance in this matter and am grateful for the support from the Stack Overflow community.

function petSounds(animal, country) {
let phrase = ''
for (let i = 0; i < animalNoises.length; i++) {
  for (let key in animalNoises[i]){
    if (animal === key){
      let sound = animalNoises[i][key][country];
      phrase = animal + 's' + ' in ' + country + ' say ' + sound
      }
    }
  }
 return phrase
}

    let animalNoises = [
  { 'dog': {
    'America' : 'Woof! Woof!',
    'Germany' : 'Wau Wau!',
    'England' : 'Bow wow!',
    'Uruguay' : 'Jua jua!',
    'Afrikaans' : 'Blaf!',
    'Korea' : 'Mong mong!',
    'Iceland' : 'Voff voff!',
    'Albania' : 'Ham!',
    'Algeria' : 'Ouaf ouaf!'
    }
  },
  { 'cat': {
    'America' : 'Meow',
    'Germany' : 'Miauw!',
    'England' : 'mew mew',
    'Uruguay' : 'Miau Miau!',
    'Afrikaans' : 'Purr',
    'Korea' : 'Nyaong!',
    'Iceland' : 'Kurnau!',
    'Albania' : 'Miau',
    'Algeria' : 'Miaou!'
    }
  },
  { 'chicken': {
    'America' : 'Cluck cluck',
    'Germany' : 'tock tock tock',
    'England' : 'Cluck Cluck',
    'Uruguay' : 'gut gut gdak',
    'Afrikaans' : 'kukeleku',
    'Korea' : 'ko-ko-ko',
    'Iceland' : 'Chuck-chuck!',
    'Albania' : 'Kotkot',
    'Algeria' : 'Cotcotcodet'
    }
  }
];

Answer №1

To improve the efficiency of your code, update your json data structure to use an object with animal types as keys:

function petSounds(animal, country) {
  const sound = animalNoises[animal][country];
  const phrase = animal + 's' + ' in ' + country + ' say ' + sound;
  return phrase;
}

let animalNoises = {
  'dog': {
    'America': 'Woof! Woof!',
    'Germany': 'Wau Wau!',
    'England': 'Bow wow!',
    'Uruguay': 'Jua jua!',
    'Afrikaans': 'Blaf!',
    'Korea': 'Mong mong!',
    'Iceland': 'Voff voff!',
    'Albania': 'Ham!',
    'Algeria': 'Ouaf ouaf!'

  },
  'cat': {
    'America': 'Meow',
    'Germany': 'Miauw!',
    'England': 'mew mew',
    'Uruguay': 'Miau Miau!',
    'Afrikaans': 'Purr',
    'Korea': 'Nyaong!',
    'Iceland': 'Kurnau!',
    'Albania': 'Miau',
    'Algeria': 'Miaou!'
  },
  'chicken': {
    'America': 'Cluck cluck',
    'Germany': 'tock tock tock',
    'England': 'Cluck Cluck',
    'Uruguay': 'gut gut gdak',
    'Afrikaans': 'kukeleku',
    'Korea': 'ko-ko-ko',
    'Iceland': 'Chuck-chuck!',
    'Albania': 'Kotkot',
    'Algeria': 'Cotcotcodet'
  }
};

console.log(petSounds('cat', 'America'));
console.log(petSounds('dog', 'Iceland'));
console.log(petSounds('chicken', 'Germany'));

Answer №2

Your approach is effective, utilizing a single for loop. However, you overlooked the inclusion of single quotes. Upon console logging, it retrieves a specific value.

animalNoises[0]['dog']['Korea']
"Mong mong!"

Within the loop, accessing values from your array requires specifying key names and country values.

The structure of the 3 animal objects does not impact the functionality.

Executing your function returns the desired outcome.

petSounds('dog', 'Korea')
"dogs in Korea say Mong mong!"

Alternatively, you can enhance your function by streamlining the inner loop as shown below:

function petSounds(animal, country) {
let phrase = ''
  for (let i = 0; i < animalNoises.length; i++) {
    let key = Object.keys(animalNoises[i])[0];
    if (animal === key){
      let sound = animalNoises[i][key][country];
      phrase = animal + 's' + ' in ' + country + ' say ' + sound
    }
  }
  return phrase
}

Answer №3

If you prefer to maintain the existing form, you can utilize an Array#find() followed by an in operator check. Afterwards, using template literals will allow you to easily construct your string.

function petSounds(animal, country) {
 const noise = animalNoises.find(obj => animal in obj)[animal][country];
 return `${animal}s in ${country} say ${noise}`
}

let animalNoises = [
  { 'dog': {
    'America' : 'Woof! Woof!',
    'Germany' : 'Wau Wau!',
    'England' : 'Bow wow!',
    'Uruguay' : 'Jua jua!',
    'Afrikaans' : 'Blaf!',
    'Korea' : 'Mong mong!',
    'Iceland' : 'Voff voff!',
    'Albania' : 'Ham!',
    'Algeria' : 'Ouaf ouaf!'
    }
  },
  { 'cat': {
    'America' : 'Meow',
    'Germany' : 'Miauw!',
    'England' : 'mew mew',
    'Uruguay' : 'Miau Miau!',
    'Afrikaans' : 'Purr',
    'Korea' : 'Nyaong!',
    'Iceland' : 'Kurnau!',
    'Albania' : 'Miau',
    'Algeria' : 'Miaou!'
    }
  },
  { 'chicken': {
    'America' : 'Cluck cluck',
    'Germany' : 'tock tock tock',
    'England' : 'Cluck Cluck',
    'Uruguay' : 'gut gut gdak',
    'Afrikaans' : 'kukeleku',
    'Korea' : 'ko-ko-ko',
    'Iceland' : 'Chuck-chuck!',
    'Albania' : 'Kotkot',
    'Algeria' : 'Cotcotcodet'
    }
  }
];

Alternatively, instead of looping twice in your version, you can simply check for existence.

It's worth noting that there are multiple methods to accomplish a task, so the above code is equivalent to:

function petSounds(animal, country) {
 const noise = animalNoises.find(obj => obj.hasOwnProperty(animal))[animal][country];
 return `${animal}s in ${country} say ${noise}`
}

In case you receive this JSON data from an external source, you could perform a reduction on it and then merge the keys and values into a master object (using Array#reduce() and Object.entries())

animalNoises = animalNoise.reduce((acc, obj) => {
  Object.entries(obj).forEach(([key, value]) => {
   acc[key] = value;
  });
  return acc;
 },
 {}
)

function petSounds(animal, country) {
  return `${animal}s in ${country} say ${animalNoises[animal][country]}`;
}

If you're interested in exploring more functionalities of Arrays, you can visit the MDN JavaScript Arrays page

The in operator offers a concise way to use Object#hasOwnProperty()

For further information on JavaScript, browse through the resources available at MDN


Here's some extra fun utilizing Object Destructuring as another method to organize your code:

function petSounds(animal, country) {
 const { [animal]: { [country]: noise } } = animalNoises.find(obj => animal in obj);
 return `${animal}s in ${country} say ${noise}`
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating new form fields dynamically using JavaScript (triggered by onClick event)

I want to dynamically add fields based on user interaction. For instance, when the checkbox or radio button is clicked, additional fields like buttons and textfields should appear. Is it possible to achieve this using onClick? If so, can you please provide ...

What could be improved in this Angular script?

angular.module('events.services', []) .factory('EventService', function($http, $cordovaSQLite) { return { fetchData: function() { return 'Data fetched successfully!'; } ...

Choose a radio button from a React Native FlatList

I am new to React Native and I'm working with the expo-radio-button component. However, I'm facing an issue where I can't seem to select only one radio button at a time in a flatlist. When I try to select a single button, it ends up select ...

What is the best way to make the cursor display as 'wait' while a script is running?

During the execution of a lengthy javascript function, I would like to change the cursor style to 'wait' and then revert it back to normal once the function is complete. I initially tried using the following code: document.body.style.cursor = &a ...

What is the process of passing data from a jQuery-AJAX function to a PHP file and how can these values be retrieved within the PHP

Here is the jQuery-AJAX function I have written: $('#request_form').submit(function(e) { var form = $(this); var stud_id = $('#stud_id').val(); var reg_date = $('#reg_date').val(); var formdata = false; var fileIn ...

Converting timestamps: Retrieve day, date, hour, minutes, etc. without utilizing the "new Date()" function

Currently developing a web-app and faced with the challenge of displaying items in a list correctly. I am working on converting the timestamp attached to each item into a readable format. For instance, 1475842129770 is transformed into Friday, 07.09.2016 ...

Guide on how to implement user authentication using React hooks and react-router

My goal is to authenticate users on each route change using react-router-dom and react hooks. When a user navigates to a route, the system should make an API call to authenticate the user. This is necessary because I am utilizing react-redux, and the Redu ...

Transferring a dynamic property from the $root instance to a child component through vue-router

How can VueJS pass a prop to a child component from the $root view instance while using vue-router? $root instance: const router = new VueRouter({ routes: [{ path: "/dashboard", component: () => import("./User/Dashboa ...

I am interested in understanding the significance of importing `Footer` before `components/Menu` in terms of import order

What is the reason behind this happening? ./pages/index.tsx 3:1 Error: The import of components/Footer/Footer should come before the import of components/Menu. This relates to import order. ...

Transform the attribute of an object into numerical form

Is there a way to convert object properties that are integers from a string to an actual numerical type? I specifically need the following conversions: Convert Lat/Long to float type Transform Date properties into numbers This snippet showcases one obj ...

Error Encountered: Unable to fulfill the request for textDocument/definition in

I am a fan of using VS Code for JavaScript and React (jsx) development. However, I sometimes encounter an issue where a panel pops up displaying the following message: [Error - 13:45:45] Request textDocument/definition failed. Message: Request textDocum ...

Struggling to transform text documents into an array

I am currently scripting in powershell to delete text files that are older than 60 days, but I am facing a problem where the script is only deleting one random file instead of all of them. I suspect this issue might be due to the fact that the files are no ...

The attribute 'NameNews' is not recognized in the specified type when running ng build --prod

Definition export interface INewsModule{ IDNews:number; IDCategoery:number; NameNews:string; TopicNews:string; DateNews?:Date; ImageCaption:string; ImageName:string ; } Implementation import { Component, OnInit, Input, I ...

The issue with style.background not functioning in Internet Explorer is causing complications

I am currently developing a JavaScript game that involves flipping cards. However, I have encountered an issue with the style.background property. It seems to be functioning correctly in Chrome but not in Internet Explorer. Here is the problematic code sn ...

Using jQuery code in the script is preventing ng-repeat from being executed

After trying to run the provided code, I am facing issues with obtaining the expected output. My goal is to validate the start date and end date, ensuring that the program's start and end dates fall within the actual start and end dates. While I have ...

Scripting issues detected in Safari and Microsoft Edge browsers

I recently finished developing an AngularJs Application that works flawlessly on Google Chrome and Mozilla Firefox. However, upon testing it on Safari and IE-11, I encountered errors in the console. One particular piece of code that causes issues is used ...

When viewing an array, the objects' values are displayed clearly; however, when attempting to access a specific value, it

I am attempting to retrieve the board_id of my objects in the columnsServer array... columnsServer: Column[]; this.service.getColumns() .subscribe(data => { this.columnsServer = data; console.log(this.columnsServer); for (this.i = 0; this.i ...

Setting up package.json to relocate node_modules to a different directory outside of the web application:

My web app is currently located in C:\Google-drive\vue-app. When I run the command yarn build, it installs a node_modules folder within C:\Google-drive\vue-app. However, since I am using Google Drive to sync my web app source code to Go ...

Accessing the statusText of a 403 response in Axios (React, Express, Node.js)

Within my component, there is a register function that makes an API call. The API checks if the email already exists and provides an appropriate status and statusText based on the result. Below is the API call handler in my Express app: router.post(' ...

Bundling JSPM with an external system JS file

Currently, I am loading my Angular2 file as a System js module from a CDN. Within my project, I have multiple files importing various System js modules of Angular2. However, I am now looking to bundle my local JavaScript files using JSPM. But when I ente ...