Home > Net >  Concatenating an array of nested objects
Concatenating an array of nested objects

Time:08-03

I tried to use the code below to concatenate multiple nested elements, and for some reason, undefined is showing up in my results.

arr = [
  {
    very_positive: ["It is certain.", "It is decidedly so.", "Without a doubt.", "Yes - definitely.", "You may rely on it."]
  },
  {
    positive: ["As I see it, yes.", "Most likely.", "Outlook good.", "Yes.", "Signs point to yes."]
  },
  {
    negative: ["Reply hazy, try again.", " Ask again later.", "Better not tell you now.", "Cannot predict now.", "Concentrate and ask again."]
  },
  {
    very_negative: ["Don't count on it.", "My reply is no.", "My sources say no.", "Outlook not so good.", "Very doubtful."]
  }
];

let flatArrObj = arr.map(list => `${list.very_positive} ${list.positive} ${list.negative} ${list.very_nagative}`)

CodePudding user response:

Array.map() takes each element of the array and applies a function to it, for concatenation you could use reduce, or more simply

arr = [{
    very_positive: ["It is certain.", "It is decidedly so.", "Without a doubt.", "Yes - definitely.", "You may rely on it."]
  },
  {
    positive: ["As I see it, yes.", "Most likely.", "Outlook good.", "Yes.", "Signs point to yes."]
  },
  {
    negative: ["Reply hazy, try again.", "Ask again later.", "Better not tell you now.", "Cannot predict now.", "Concentrate and ask again."]
  },
  {
    very_negative: ["Don't count on it.", "My reply is no.", "My sources say no.", "Outlook not so good.", "Very doubtful."]
  }
];

let flatObj = [...arr[0].very_positive, ...arr[1].positive,  ...arr[2].negative,  ...arr[3].very_negative]

console.log(flatObj);

given your data structure.

CodePudding user response:

arr = [{
    very_positive: ["It is certain.", "It is decidedly so.", "Without a doubt.", "Yes - definitely.", "You may rely on it."]
  },
  {
    positive: ["As I see it, yes.", "Most likely.", "Outlook good.", "Yes.", "Signs point to yes."]
  },
  {
    negative: ["Reply hazy, try again.", " Ask again later.", "Better not tell you now.", "Cannot predict now.", "Concentrate and ask again."]
  },
  {
    very_negative: ["Don't count on it.", "My reply is no.", "My sources say no.", "Outlook not so good.", "Very doubtful."]
  }
];
let result = [];
// INSERTING VALUE AT SPECIFIC INDEX
function insertAt(array, index, ...elementsArray) {
  array.splice(index, 0, ...elementsArray);
}
// INSERTING OBJECT VALUES 
const pushInResult = (obj) => {
  Object.values(obj).forEach(value => insertAt(result, 0, ...value));
}
// LOOPING THOUGH ARRAY
arr.forEach(obj => pushInResult(obj));
// PRINTING FINAL ARRAY RESULT
console.log(result);

CodePudding user response:

Upon looking at this question for the first time, I was like "Concentrate and ask again" :/

Your data structure for the arr seems confusing, with each element being a map with only 1 entry. I suppose you would want to make each element in the array a key-value pair because that seems to be the intention here.

Thus, I would rewrite your data structure like this:

let obj = {
    very_positive: ["It is certain.", "It is decidedly so.", "Without a doubt.", "Yes - definitely.", "You may rely on it."],
    positive: ["As I see it, yes.", "Most likely.", "Outlook good.", "Yes.", "Signs point to yes."],
    negative: ["Reply hazy, try again.", " Ask again later.", "Better not tell you now.", "Cannot predict now.", "Concentrate and ask again."],
    very_negative: ["Don't count on it.", "My reply is no.", "My sources say no.", "Outlook not so good.", "Very doubtful."]
}; // I am guessing that you're making an 8-ball, cool!

On this part, your question wasn't really clear. Do I concatenate each category's responses, or do I combine every single response into one string?

You can use the Array.prototype.join method for joining the strings together. The join method "joins" the elements inside it, presumably Strings (if not, that element will be coerced to a String somehow.) You can optionally pass inside the method a separator that is put between the elements. Array.prototype.join MDN Docs

Example:

let array = ["bread", "peanut", "butter"];
console.log(array.join()); // Should output breadpeanutbutter
console.log(array.join("-")); // Should output bread-peanut-butter

Since you need to apply this join method to each and every element in the array, you can and have used the method Array.prototype.map. Array.prototype.map MDN Docs

Example:

let arr = [1, 2, 3, 4];
console.log(arr.map(num => num * num)); // Should output Array 1, 4, 9, 16

Since all of the above methods only work with Arrays, you can use either Object.keys(obj) to get all the keys of an object as an array, or Object.values(obj) to get the values instead to do things with it, which is what I do here. Object.values MDN Docs

Example:

let obj = {a: 1, b: 2, c: 3};
console.log(Object.values(obj)); // Should output Array [1, 2, 3]
console.log(Object.keys(obj)); // Should output Array ["a", "b", "c"]

Skip this code if "combining everything together" is your intention! Screw my 30 minutes of intensive writing!

Using everything above, your code can look like this:

const eight_ball_responses = { // Snazzy name, I know
  very_positive: ["It is certain.", "It is decidedly so.", "Without a doubt.", "Yes - definitely.", "You may rely on it."],
  positive: ["As I see it, yes.", "Most likely.", "Outlook good.", "Yes.", "Signs point to yes."],
  negative: ["Reply hazy, try again.", " Ask again later.", "Better not tell you now.", "Cannot predict now.", "Concentrate and ask again."],
  very_negative: ["Don't count on it.", "My reply is no.", "My sources say no.", "Outlook not so good.", "Very doubtful."]
};

const flat_eight_ball_responses = Object
  .values(eight_ball_responses) // Get all the responses of the 8-ball
  .map(responses => responses.join(" ")); // Join each category's array of responses, which leaves an array of 4 strings for each category
  
console.log(flat_eight_ball_responses);
// For the question author: you might want to use flat_eight_ball_responses.join() instead, depending on your intention. The question wasn't really clear on this.

If you log the resulting object, it should look something like:

["It is certain. It is decidedly so. Without a doubt. Yes - definitely. You may rely on it.", "As I see it, yes. Most likely. Outlook good. Yes. Signs point to yes.", "Reply hazy, try again.  Ask again later. Better not tell you now. Cannot predict now. Concentrate and ask again.", "Don't count on it. My reply is no. My sources say no. Outlook not so good. Very doubtful."]

or even:

It is certain. It is decidedly so. Without a doubt. Yes - definitely. You may rely on it. As I see it, yes. Most likely. Outlook good. Yes. Signs point to yes. Reply hazy, try again. Ask again later. Better not tell you now. Cannot predict now. Concentrate and ask again. Don't count on it. My reply is no. My sources say no. Outlook not so good. Very doubtful.

Instead of a new array, you can probably also modify the object in place too, and preserve the category names.

const eight_ball_responses = { // Snazzy name, I know
  very_positive: ["It is certain.", "It is decidedly so.", "Without a doubt.", "Yes - definitely.", "You may rely on it."],
  positive: ["As I see it, yes.", "Most likely.", "Outlook good.", "Yes.", "Signs point to yes."],
  negative: ["Reply hazy, try again.", " Ask again later.", "Better not tell you now.", "Cannot predict now.", "Concentrate and ask again."],
  very_negative: ["Don't count on it.", "My reply is no.", "My sources say no.", "Outlook not so good.", "Very doubtful."]
};

// Using Objects.entries give both the key and the value in one array/tuple
for (const [category, responses] of Object.entries(eight_ball_responses)) {
  eight_ball_responses[category] = responses.join(" ");
}

console.log(eight_ball_responses);

very-positive! (which means cheers, dear lord)

  • Related