0

I am trying to add objects formatted as {title: value} to an array. I wrote the following function

const newResults = resultData.map(result => {
  let results = [];
  if (result.INTELLCONT.length > 1) {
    for (let i = 0; i < result.INTELLCONT.length; i++) {
      results.push({
        title: result.INTELLCONT[i].TITLE._text,
      });
    }
  } else {
    results.push({
      title: result.INTELLCONT.TITLE._text,
    });
  }
  return results;
});

But the array being returned looks like this

[Array(3), Array(1), Array(4), Array(1), Array(2), Array(1), Array(4)]

I want it to look like this

[{title: value}, {title: value}, {title: value}, {title: value}, {title: value}, ... ]

What am I doing wrong?

3
  • 1
    use .map().flat(). Commented Jan 7, 2020 at 16:07
  • 1
    because you are pushing arrays into an index in an array, that is how map works. You probably want reduce or use concat Commented Jan 7, 2020 at 16:07
  • The line with result.INTELLCONT.TITLE._text is accurate? Because it seems like result.INTELLCONT is an array and you'd need to change that to result.INTELLCONT[0].TITLE._text. Commented Jan 7, 2020 at 16:39

4 Answers 4

1

With map you are pusing an array into each index. So it is working as expected. Use reduce instead of map so you will just push it to one array and not have to do extra work afterwards to flatten it.

const newResults = resultData.reduce((results, result) => {
  if (result.INTELLCONT.length > 1) {
    for (let i = 0; i < result.INTELLCONT.length; i++) {
      results.push({
        title: result.INTELLCONT[i].TITLE._text,
      });
    }
  } else {
    results.push({
      title: result.INTELLCONT.TITLE._text,
    });
  }
  return results;
}, []);
Sign up to request clarification or add additional context in comments.

1 Comment

Did you mean to write resultData.reduce instead of resultData.map?
1

the problem is that you are using Map, and according to the documentation

map calls a provided callback function once for each element in an array, in order, and constructs a new array from the results

so basically, you are doing:

let results = [];
.....
return results

and therefore, each entry of your array will be converted(mapped) to an array.

in order to solve this, you can use Flat in order to get what you want.

const newResults = resultData.map(result => {
  let results = [];
  if (result.INTELLCONT.length > 1) {
    for (let i = 0; i < result.INTELLCONT.length; i++) {
      results.push({
        title: result.INTELLCONT[i].TITLE._text,
      });
    }
  } else {
    results.push({
      title: result.INTELLCONT.TITLE._text,
    });
  }
  return results;
})
.flat();

Comments

1

use Array.reduce instead of Array.map because map returns one value for each element of the input array.

let accumulatorInitiator = []
const newResults = resultData.reduce((accumulator, result) => {;
  if (result.INTELLCONT.length > 1) {
    for (let i = 0; i < result.INTELLCONT.length; i++) {
      accumulator.push({
        title: result.INTELLCONT[i].TITLE._text,
      });
    }
  } else {
    accumulator.push({
      title: result.INTELLCONT.TITLE._text,
    });
  }
  return accumulator;
}, accumulatorInitiator);

Comments

1

As @random stated, you can use add .flat after your call to .map since that would create an array of arrays, which you'd want to flatten after.


Alternatively, you can do it in a single pass by just adding the items into a new array:

const resultData = [
  {INTELLCONT: [{TITLE: {"_text": "A"}}, {TITLE: {"_text": "B"}}, {TITLE: {"_text": "C"}}]},
  {INTELLCONT: [{TITLE: {"_text": "D"}}, {TITLE: {"_text": "E"}}, {TITLE: {"_text": "F"}}]},
  {INTELLCONT: [{TITLE: {"_text": "G"}}]},
  {INTELLCONT: [{TITLE: {"_text": "H"}}, {TITLE: {"_text": "I"}}, {TITLE: {"_text": "J"}}, {TITLE: {"_text": "K"}}]},
  {INTELLCONT: [{TITLE: {"_text": "L"}}]},
  {INTELLCONT: [{TITLE: {"_text": "M"}}, {TITLE: {"_text": "N"}}]},
  {INTELLCONT: [{TITLE: {"_text": "O"}}]},
  {INTELLCONT: [{TITLE: {"_text": "P"}}, {TITLE: {"_text": "Q"}}, {TITLE: {"_text": "R"}}, {TITLE: {"_text": "S"}}]},
];

const newResults = [];
resultData.forEach(result => {
  if (result.INTELLCONT.length > 1) {
    for (let i = 0; i < result.INTELLCONT.length; i++) {
      newResults.push({
        title: result.INTELLCONT[i].TITLE._text,
      });
    }
  } else {
    newResults.push({
      title: result.INTELLCONT[0].TITLE._text,
    });
  }
});

console.log(newResults);


If resultData can be iterated through, you can simplify even more by using .flatMap:

const resultData = [
  {INTELLCONT: [{TITLE: {"_text": "A"}}, {TITLE: {"_text": "B"}}, {TITLE: {"_text": "C"}}]},
  {INTELLCONT: [{TITLE: {"_text": "D"}}, {TITLE: {"_text": "E"}}, {TITLE: {"_text": "F"}}]},
  {INTELLCONT: [{TITLE: {"_text": "G"}}]},
  {INTELLCONT: [{TITLE: {"_text": "H"}}, {TITLE: {"_text": "I"}}, {TITLE: {"_text": "J"}}, {TITLE: {"_text": "K"}}]},
  {INTELLCONT: [{TITLE: {"_text": "L"}}]},
  {INTELLCONT: [{TITLE: {"_text": "M"}}, {TITLE: {"_text": "N"}}]},
  {INTELLCONT: [{TITLE: {"_text": "O"}}]},
  {INTELLCONT: [{TITLE: {"_text": "P"}}, {TITLE: {"_text": "Q"}}, {TITLE: {"_text": "R"}}, {TITLE: {"_text": "S"}}]},
];

const newResults = resultData.flatMap(result => result.INTELLCONT.map(r => ({title: r.TITLE._text})));

console.log(newResults)

Alternatively:

const resultData = [
  {INTELLCONT: [{TITLE: {"_text": "A"}}, {TITLE: {"_text": "B"}}, {TITLE: {"_text": "C"}}]},
  {INTELLCONT: [{TITLE: {"_text": "D"}}, {TITLE: {"_text": "E"}}, {TITLE: {"_text": "F"}}]},
  {INTELLCONT: [{TITLE: {"_text": "G"}}]},
  {INTELLCONT: [{TITLE: {"_text": "H"}}, {TITLE: {"_text": "I"}}, {TITLE: {"_text": "J"}}, {TITLE: {"_text": "K"}}]},
  {INTELLCONT: [{TITLE: {"_text": "L"}}]},
  {INTELLCONT: [{TITLE: {"_text": "M"}}, {TITLE: {"_text": "N"}}]},
  {INTELLCONT: [{TITLE: {"_text": "O"}}]},
  {INTELLCONT: [{TITLE: {"_text": "P"}}, {TITLE: {"_text": "Q"}}, {TITLE: {"_text": "R"}}, {TITLE: {"_text": "S"}}]},
];

const newResults2 = resultData.flatMap(result => result.INTELLCONT).map(r => ({title: r.TITLE._text}));

console.log(newResults2)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.