Filter out Non null and undefined items based on a property from an array of objects

Viewed 135

How can i filter items from an array of objects with conditional check on a property of type string

My JSON is like this

{"startIndex":2,"selections":[{"type":"SKU","colIndex":0,"values":[{"value":1231319,"bgcolour":"","textcolour":"","type":1,"colIndex":0,"rowIndex":2,"selected":false},{"value":1231320,"bgcolour":"","textcolour":"","type":1,"colIndex":0,"rowIndex":3,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":0,"rowIndex":4,"selected":false},{"value":1231322,"bgcolour":"","textcolour":"","type":1,"colIndex":0,"rowIndex":5,"selected":false},{"value":1231323,"bgcolour":"","textcolour":"","type":1,"colIndex":0,"rowIndex":6,"selected":false},{"value":1231324,"bgcolour":"","textcolour":"","type":1,"colIndex":0,"rowIndex":7,"selected":false},{"value":1231325,"bgcolour":"","textcolour":"","type":1,"colIndex":0,"rowIndex":8,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":0,"rowIndex":9,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":0,"rowIndex":10,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":0,"rowIndex":11,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":0,"rowIndex":12,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":0,"rowIndex":13,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":0,"rowIndex":14,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":0,"rowIndex":15,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":0,"rowIndex":16,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":0,"rowIndex":17,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":0,"rowIndex":18,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":0,"rowIndex":19,"selected":false}]},{"type":"QTY","colIndex":1,"values":[{"value":2,"bgcolour":"","textcolour":"","type":1,"colIndex":1,"rowIndex":2,"selected":false},{"value":1,"bgcolour":"","textcolour":"","type":1,"colIndex":1,"rowIndex":3,"selected":false},{"value":-1,"bgcolour":"","textcolour":"","type":1,"colIndex":1,"rowIndex":4,"selected":false},{"value":0,"bgcolour":"","textcolour":"","type":0,"colIndex":1,"rowIndex":5,"selected":false},{"value":1,"bgcolour":"","textcolour":"","type":1,"colIndex":1,"rowIndex":6,"selected":false},{"value":2,"bgcolour":"","textcolour":"","type":1,"colIndex":1,"rowIndex":7,"selected":false},{"value":3,"bgcolour":"","textcolour":"","type":1,"colIndex":1,"rowIndex":8,"selected":false},{"value":1,"bgcolour":"","textcolour":"","type":1,"colIndex":1,"rowIndex":9,"selected":false},{"value":"Some more products under a merged cell just to be annoying","bgcolour":"","textcolour":"","type":0,"colIndex":1,"rowIndex":10,"selected":false},{"value":"product ID","bgcolour":"","textcolour":"","type":0,"colIndex":1,"rowIndex":11,"selected":false},{"value":333444,"bgcolour":"","textcolour":"","type":1,"colIndex":1,"rowIndex":12,"selected":false},{"value":333445,"bgcolour":"","textcolour":"","type":1,"colIndex":1,"rowIndex":13,"selected":false},{"value":333446,"bgcolour":"","textcolour":"","type":1,"colIndex":1,"rowIndex":14,"selected":false},{"value":333447,"bgcolour":"","textcolour":"","type":1,"colIndex":1,"rowIndex":15,"selected":false},{"value":333448,"bgcolour":"","textcolour":"","type":1,"colIndex":1,"rowIndex":16,"selected":false},{"value":333449,"bgcolour":"","textcolour":"","type":1,"colIndex":1,"rowIndex":17,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":1,"rowIndex":18,"selected":false},{"value":333451,"bgcolour":"","textcolour":"","type":1,"colIndex":1,"rowIndex":19,"selected":false}]},{"type":"Name","colIndex":2,"values":[{"value":"BRONZE HAT","bgcolour":"","textcolour":"","type":0,"colIndex":2,"rowIndex":2,"selected":true},{"value":"GOLD HAT","bgcolour":"","textcolour":"","type":0,"colIndex":2,"rowIndex":3,"selected":true},{"value":"unknown?","bgcolour":"","textcolour":"","type":0,"colIndex":2,"rowIndex":4,"selected":true},{"value":8,"bgcolour":"","textcolour":"","type":1,"colIndex":2,"rowIndex":5,"selected":true},{"value":"this data is a bit messy%","bgcolour":"","textcolour":"","type":0,"colIndex":2,"rowIndex":6,"selected":true},{"value":"Trouser A","bgcolour":"","textcolour":"","type":0,"colIndex":2,"rowIndex":7,"selected":true},{"value":"Trouser B","bgcolour":"","textcolour":"","type":0,"colIndex":2,"rowIndex":8,"selected":true},{"bgcolour":"","textcolour":"","type":0,"colIndex":2,"rowIndex":9,"selected":true},{"bgcolour":"","textcolour":"","type":0,"colIndex":2,"rowIndex":10,"selected":true},{"value":"quantity required","bgcolour":"","textcolour":"","type":0,"colIndex":2,"rowIndex":11,"selected":true},{"value":2,"bgcolour":"","textcolour":"","type":1,"colIndex":2,"rowIndex":12,"selected":true},{"value":1,"bgcolour":"","textcolour":"","type":1,"colIndex":2,"rowIndex":13,"selected":true},{"value":-1,"bgcolour":"","textcolour":"","type":1,"colIndex":2,"rowIndex":14,"selected":true},{"bgcolour":"","textcolour":"","type":0,"colIndex":2,"rowIndex":15,"selected":true},{"value":1,"bgcolour":"","textcolour":"","type":1,"colIndex":2,"rowIndex":16,"selected":true},{"value":2,"bgcolour":"","textcolour":"","type":1,"colIndex":2,"rowIndex":17,"selected":true},{"value":3,"bgcolour":"","textcolour":"","type":1,"colIndex":2,"rowIndex":18,"selected":true},{"value":1,"bgcolour":"","textcolour":"","type":1,"colIndex":2,"rowIndex":19,"selected":true}]}]}

I am using the following typescript but still all items are returned

 var selected_skus = this.selectionSettings.selections.filter(e => e.type === 'SKU' && e.values.filter(x=>x.value?.length >0 ))
      .map(obj => obj.values);
    console.log(selected_skus);

How can i ensure that items with a not null x.value is returning back

3 Answers
e.values.filter(x=>x.value?.length > 0)

will always return an array. it might be an empty array [] - but it will still be an array. and arrays are "truthy" - so the second part oft

e => e.type === 'SKU' && e.values.filter(x=>x.value?.length > 0)

will evaluate to true either way. empty array or not.

what you will have to do instead is to check if the length of the filtered array is > 0, so

(e => e.type === 'SKU') && (e.values.filter(x=>x.value?.length > 0).length > 0)

but also your inner check of

x.value?.length > 0

doesn't really make sense since you are checking numbers there. checking on a length property of type number is not what you want. so in the end you will need

(e => e.type === 'SKU') && (e.values.filter(x => x !== null && x !== undefined).length > 0)

You can't using filters inside of filters in this way. You're looking to filter by SKU, and then for each matching set of skus map the values array over. Additionally the .length property exists on strings, so we cast it as a string to check.

json.selections.filter(e => e.type === 'SKU') // first get an array of all SKU sets
    .map(s => ({...s,  values:s.values // map each set of SKUs, transforming the values array within
                 .filter(x=>x.value?.toString().length >0 )})) // filter that property exists && is is not empty

let json = {"startIndex":2,"selections":[{"type":"SKU","colIndex":0,"values":[{"value":1231319,"bgcolour":"","textcolour":"","type":1,"colIndex":0,"rowIndex":2,"selected":false},{"value":1231320,"bgcolour":"","textcolour":"","type":1,"colIndex":0,"rowIndex":3,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":0,"rowIndex":4,"selected":false},{"value":1231322,"bgcolour":"","textcolour":"","type":1,"colIndex":0,"rowIndex":5,"selected":false},{"value":1231323,"bgcolour":"","textcolour":"","type":1,"colIndex":0,"rowIndex":6,"selected":false},{"value":1231324,"bgcolour":"","textcolour":"","type":1,"colIndex":0,"rowIndex":7,"selected":false},{"value":1231325,"bgcolour":"","textcolour":"","type":1,"colIndex":0,"rowIndex":8,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":0,"rowIndex":9,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":0,"rowIndex":10,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":0,"rowIndex":11,"selected":false},{"bgcolour":"","textcolour":"","type":0,"colIndex":0,"rowIndex":19,"selected":false}]}]}
let selected_skus = json.selections.filter(e => e.type === 'SKU').map(s => ({...s, values:s.values.filter(x=> x.value?.toString().length >0 )}))
console.log(selected_skus)

First filter by type "SKU" then map the filtered data and for each item filter the data.values property, and assign the filtered values to data.values property.

let selectionSettings = {
  "startIndex": 2, "selections": [
    {
      "type": "SKU", "colIndex": 0, "values":
        [{ "value": 1231319, "bgcolour": "", "textcolour": "", "type": 1, "colIndex": 0, "rowIndex": 2, "selected": false },
        { "value": 1231320, "bgcolour": "", "textcolour": "", "type": 1, "colIndex": 0, "rowIndex": 3, "selected": false },
        { "bgcolour": "", "textcolour": "", "type": 0, "colIndex": 0, "rowIndex": 4, "selected": false },
        { "value": 1231322, "bgcolour": "", "textcolour": "", "type": 1, "colIndex": 0, "rowIndex": 5, "selected": false },
        { "value": 1231323, "bgcolour": "", "textcolour": "", "type": 1, "colIndex": 0, "rowIndex": 6, "selected": false },
        { "value": 1231324, "bgcolour": "", "textcolour": "", "type": 1, "colIndex": 0, "rowIndex": 7, "selected": false }]
    },
    {
      "type": "QTY", "colIndex": 1, "values":
        [{ "value": 2, "bgcolour": "", "textcolour": "", "type": 1, "colIndex": 1, "rowIndex": 2, "selected": false },
        { "value": 1, "bgcolour": "", "textcolour": "", "type": 1, "colIndex": 1, "rowIndex": 3, "selected": false },
        { "value": -1, "bgcolour": "", "textcolour": "", "type": 1, "colIndex": 1, "rowIndex": 4, "selected": false },
        { "value": 0, "bgcolour": "", "textcolour": "", "type": 0, "colIndex": 1, "rowIndex": 5, "selected": false }]
    }
  ]
};

const filterList = (list) => {
  return list.selections.filter(e => e.type === 'SKU')
    .map(data => {
      data.values = data.values.filter(({value}) => !(value === undefined || value === null));
      return data;
    });
}

console.log(filterList(selectionSettings));

Related