0

I need to replace nested arrays inside a main array that have null values like lets say [null, null] or the nested arrays that are empty with a string value like "empty".

Saying that we have the following array:

array = [
  {
    id: 123, 
    name: 'Peter',
    phone: [null, null],
    addresses: [{ address1: 'Manchester, UK', address2: 'London, UK' }]
  },
  {
    id: 124,
    name: 'Sara',
    phone: [],
    addresses: [{ address1: 'London, UK', address2: 'Paris, FR' }]
  }
];

We see that, the first array has phone: [null, null] and the second has it as []. What I need to do it to transform them into the following:

array = [
  {
    id: 123, 
    name: 'Peter',
    phone: "empty",
    addresses: [{ address1: 'Manchester, UK', address2: 'London, UK' }]
  },
  {
    id: 124,
    name: 'Sara',
    phone: "empty",
    addresses: [{ address1: 'London, UK', address2: 'Paris, FR' }]
  }
];

This is an example, and each array might contain multiple nested arrays that have the same [null, null] or [].

I tried the following:

var filtered = this.array.map(subarray => subarray.filter(el => el != null));

from this Stack Overflow answer, but I've got an error saying:

Error: subarray.filter is not a function

Then I tried a second method using lodash's every() and isNull method and property but couldn't figure it out:

let props = [];
props = Array.from(new Set(this.array.flatMap(e => Object.keys(e), [])));
console.log(props)
for (const prop of props) {
  this.array.forEach(e => {
    if ((Array.isArray(e[prop]) || typeof(e[prop]) === 'object') && e[prop]._.every(_.isNull)) {
      console.log(e)
    }
  });
}

I searched few questions on Stack Overflow but the structure of the arrays are like: [ [1, 2], [1,3]...] and not like my array's structure [{...}, {...}], so I tried some of the solution and got the same error of method 1 above.

Here is a stackblitz.

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
alim1990
  • 4,656
  • 12
  • 67
  • 130
  • will the `[]` or `[null, null]` array always be a value of the `phone` property or do you want to replace all occurrence of `[null, null]` throughout the entire object (regardless of what its property/key is) – Nick Parsons Apr 06 '20 at 13:33
  • Some users have already phone numbers, some don't. And I am giving an example about phone numbers here, but there is other fields in my data that may encounter the same issue. – alim1990 Apr 06 '20 at 13:34

2 Answers2

1

First loop through the array, and within each object, you can set the phone property:

for(const entry of array) {
    const isEmpty = entry.phone.filter(p => p !== null).length === 0;
    entry.phone = isEmpty ? 'empty' : entry.phone;
}

Caveat is that this edits your array. One concern about the premise of the question is that you are setting an array property to a string, which is not ideal.

Live Example: https://jsfiddle.net/michaschwab/9ze3p2or/3/, and here's your edited stackblitz: https://stackblitz.com/edit/null-nested-array-into-string-jwhfwn

If you want to not modify your array, this is a way to do it:

const modified = array.map(entry => {
  return {...entry, // Copy previous values
    phone: entry.phone.filter(p => p !== null).length === 0 ? 'empty' : entry.phone
  };
});
Micha Schwab
  • 786
  • 1
  • 6
  • 21
  • Thanks. The weird thing that I am keep getting ` Cannot read property 'filter' of null` on my visual studio code – alim1990 Apr 06 '20 at 13:51
  • I found out that when a field of an array even if it was not an array, like a string but with `null` as follow, here it is returning the error. Please consider that here the `phone` is an example, I need to loop over all the properties of my array that have type object of array and check if null or empty – alim1990 Apr 06 '20 at 14:02
  • Are you saying that the keys can also have null as value? – Micha Schwab Apr 06 '20 at 14:40
1

Map the array, and use _.mapValues() on each object. For each values that is an array, and full of null values, return 'empty':

const array = [{"id":123,"name":"Peter","phone":[null,null],"addresses":[{"address1":"Manchester, UK","address2":"London, UK"}]},{"id":124,"name":"Sara","phone":[],"addresses":[{"address1":"London, UK","address2":"Paris, FR"}]}];

const result = array.map(o => 
  _.mapValues(o, v => // map the values of the object
    _.isArray(v) && v.every(_.isNull) ? 'empty' : v // if a value is an array, and all values are null return 'empty'
  )
);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
Ori Drori
  • 183,571
  • 29
  • 224
  • 209