1

I need to extract listImages that have a status of 'Existing` inside of an array. My problem is that it gets its parent array.

Data

lists = [
  {
    "listID": "1",
    "listImages": [
      {
        "id": "111",
        "status": "Existing"
      },
      {
        "id": "222",
        "status": "Non-Existing"
      }
    ]
  },
  {
    "listID": "2",
    "listImages": [
      {
        "id": "333",
        "status": "Non-Existing"
      }
    ]
  }
]

Current Code

const images = lists.map((list) => ({
  ...list,
  listImages: (list.listImages?? []).filter(
    ({ status }) => status === "Existing"
  ),
}));

Expected Output

["111"]
1
  • Your code doesn't seem to be much helpful as it will return array of objects, whereas you need an array of primitives. I would use Array.prototype.reduce(), like: lists.reduce((acc, {listImages}) => (listImages.forEach(({id, status}) => status === 'Existing' && acc.push(id)), acc), []) Commented Nov 26, 2021 at 8:21

2 Answers 2

3

Looks like you just want to get the id. Simply do filter followed by a map for each list. If you want to do this process on all lists and merge the arrays to one, use flatMap.

lists = [
  {
    "listID": "1",
    "listImages": [
      {
        "id": "111",
        "status": "Existing"
      },
      {
        "id": "222",
        "status": "Non-Existing"
      }
    ]
  },
  {
    "listID": "2",
    "listImages": [
      {
        "id": "333",
        "status": "Non-Existing"
      }
    ]
  }
];

const images = lists.flatMap( list => list.listImages.filter(image => image.status === "Existing").map(image => image.id));
console.log(images);

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

2 Comments

Your code will loop unnecessarily twice over each item of each listImages array: first time - to find the matching items and second time to extract the id. For large number of items that may become a performance issue.
Just to have an idea of how much you may hurt performance with those unnecessary iterations: jsbench.me/dwkwg5eayd/1
0

Here you have both imperative and declarative solutions. You can change named functions to arrow functions and make it even a single line but I don't think that we have to follow that ugly coding style where no one (not even future you) understands the code.

lists = [
  {
    "listID": "1",
    "listImages": [
      {
        "id": "111",
        "status": "Existing"
      },
      {
        "id": "222",
        "status": "Non-Existing"
      }
    ]
  },
  {
    "listID": "2",
    "listImages": [
      {
        "id": "333",
        "status": "Non-Existing"
      }
    ]
  }
]

// Imperative solution
const images = [];

lists.forEach(list => {
  list.listImages.forEach(image => {
    if(image.status === 'Existing'){
      images.push(image.id);
    }
  })
});
console.log(images);

// Declarative solution
const data = lists.flatMap(function getAllImages(list){
   return list.listImages;
}).filter(function getExistingImages(image) {
  return image.status === 'Existing';
}).map(function getIds(image){ 
 return image.id
});

console.log(data);

2 Comments

verbosity !== readability
You are saying that the reader should read the function body to understand what function is during. I can't agree there

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.