2

I have an array of objects, and each of those objects may contain children, which is another array of the same structure. I want to concatenate values of each object into a list of strings delimited with a character.

For example:

var array = [{
    "text": "one",
    "children": [
      {
        "text": "two",
        "children": [
          {
            "text": "foo"
          },
          {
            "text": "bar"
          },
          {
            "text": "baz"
          }
        ]
      },
      {
        "text": "three",
        "children": [
          {
            "text": "foo"
          },
          {
            "text": "bar"
          },
          {
            "text": "baz"
          }
        ]
      }
    ]
}, {
    "text": "two",
    "children": [
      {
        "text": "hello",
        "children": [
          {
            "text": "world"
          },
          {
            "text": "planet"
          }
        ]
      }
    ]
}];

Would result in:

[
    "one two foo",
    "one two bar",
    "one two baz",
    "one three foo",
    "one three bar",
    "one three baz",
    "two hello world",
    "two hello planet"
];

Is there any way this can be achieved using Lodash?

2 Answers 2

1

My solution:

function concatString(currentString, object) {
  let string = currentString;

  if (object.text) {
    string = string + ' ' + object.text;
  }

  if (object.children) {
    string = object.children.map(item => concatString(string, item));
  }

  return string;
}

const result = _.flattenDeep(array.map(arrayItem => concatString('', arrayItem)));

https://jsfiddle.net/tqcj18so/1/

Sign up to request clarification or add additional context in comments.

1 Comment

I accepted this answer instead as it uses Lodash as requested.
1

You can use Array#map recursively to collect the strings, and then flatten the results using Array#concat.

ES6:

const array = [{"text":"one","children":[{"text":"two","children":[{"text":"foo"},{"text":"bar"},{"text":"baz"}]},{"text":"three","children":[{"text":"foo"},{"text":"bar"},{"text":"baz"}]}]},{"text":"two","children":[{"text":"hello","children":[{"text":"world"},{"text":"planet"}]}]}];

const collect = (arr, pre = '') => {
  return [].concat([], ...arr.map((item) => {
    const label = `${pre} ${item.text}`.trim();
  
    return item.children ? collect(item.children, label) : label;
  }));
}

const result = collect(array);

console.log(result);

ES5:

var array = [{"text":"one","children":[{"text":"two","children":[{"text":"foo"},{"text":"bar"},{"text":"baz"}]},{"text":"three","children":[{"text":"foo"},{"text":"bar"},{"text":"baz"}]}]},{"text":"two","children":[{"text":"hello","children":[{"text":"world"},{"text":"planet"}]}]}];

function collect (arr, pre) {
  return [].concat.apply([], arr.map(function(item) {
    var label = (pre + ' ' + item.text).trim();
  
    return item.children ? collect(item.children, label) : label;
  }));
}

var result = collect(array, '');

console.log(result);

2 Comments

Ah, so there's no way to achieve this directly in Lodash? This works better than what I had already, and it's a lot smaller. Thanks!
@BeautifulChaos - lodash doesn't contain any method to recursively combine properties as far as I know. Welcome :)

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.