0

I have code as follows:

data = [
  {id: "15130", state: "INITIAL"},
  {id: "15129", state: "LOCKED"},
  {id: "10314", state: "APPROVED"},
  {id: "51", state: "APPROVED"},
  {id: "10313", state: "APPROVED_LOCKED"},
  {id: "10315", state: "APPROVED_LOCKED"}
]

filters = [{id: "2", name: "LOCKED", count: 2}]

let result = []

_.forEach(data, (ca) => {  
  if (filters.length > 0) {
    if (!_.some(filters, (item) => item.name === ca.state.includes('LOCKED') ? "LOCKED" : ca.state))
      return;
  }
  result.push(ca);
});

console.log(result)

I want to get all records from data where state includes "LOCKED". Thus result should be:

result = [
  {id: "15129", state: "LOCKED"},
  {id: "10313", state: "APPROVED_LOCKED"},
  {id: "10315", state: "APPROVED_LOCKED"}
]

But I get all records in result.

Here is the fiddle.

Any idea what I do wrong?

2
  • does count have a meaning here? Commented May 23, 2019 at 7:08
  • @NinaScholz No. Its only name what matters. Commented May 23, 2019 at 7:09

5 Answers 5

2

No need for Lodash, you can use Vanilla JavaScript's Array.filter(), followed by Array.includes() which checks if the string value in state contains the string 'LOCKED'.

const data = [
  {id: "15130", state: "INITIAL"},
  {id: "15129", state: "LOCKED"},
  {id: "10314", state: "APPROVED"},
  {id: "51", state: "APPROVED"},
  {id: "10313", state: "APPROVED_LOCKED"},
  {id: "10315", state: "APPROVED_LOCKED"}
]

const res = data.filter(obj => obj['state'].includes('LOCKED'));

console.log(res);

However, do take note that Array.includes() is not as widely supported.

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

5 Comments

I can also have filters = [{id: "2", name: "LOCKED", count: 2}, {id: "1", name: "APPROVED", count: 2}]
@Boky I see! Basically, filter the records whereby state can include 'LOCKED' or 'APPROVED'?
APPROVED is always APPROVED, but with LOCKED I can have LOCKED_APPROVED, LOCKED_INITIAL and LOCKED. Thus for APPROVED I do not need includes, it can be === but for LOCKED I need includes.
I think it would be cleaner to have a list of exact matches you want to exclude, rather than do a partial match on the state. Imagine in the future a state shows up that's "UNLOCKED", at which point it partially matches "LOCKED" and it gets filtered out. EDIT: just to clarify - this was aimed at OP. This solution only follows OP's request.
In that case, it follows a similar logic - iterate through the list of filters, and conditionally handle it based on the state?
0

You could filter the array by checking each name of the filters array.

var data = [{ id: "15130", state: "INITIAL" }, { id: "15129", state: "LOCKED" }, { id: "10314", state: "APPROVED" }, { id: "51", state: "APPROVED" }, { id: "10313", state: "APPROVED_LOCKED" }, { id: "10315", state: "APPROVED_LOCKED" }],
    filters = [{ id: "2", name: "LOCKED", count: 2 }, { id: "1", name: "APPROVED", count: 2 }],
    result = data.filter(({ state }) => filters.some(({ name }) => state.includes(name)));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

0
const allowedStatus = ["APPROVED_LOCKED", "LOCKED" ];

data.filter(filter => allowedStatus.includes(filter.state));

You can have an array with allowd status and filter the data with that. Try above code.

Comments

0

How to do it with lodash:

Since you do not need to modify the original array, you may use _.filter . The required arguments are the input array and the predicate which will be used to filter the provided array.

    const data = [
      {id: "15130", state: "INITIAL"},
      {id: "15129", state: "LOCKED"},
      {id: "10314", state: "APPROVED"},
      {id: "51", state: "APPROVED"},
      {id: "10313", state: "APPROVED_LOCKED"},
      {id: "10315", state: "APPROVED_LOCKED"}
    ]

    const result = _.filter(data, (elem => {return elem.state.includes("LOCKED")}));

    console.log(result);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

In case you want to modify the original array, _.remove is an option.

Comments

0

You can use pure JS:

 

const data = [
  {id: "15130", state: "INITIAL"},
  {id: "15129", state: "LOCKED"},
  {id: "10314", state: "APPROVED"},
  {id: "51", state: "APPROVED"},
  {id: "10313", state: "APPROVED_LOCKED"},
  {id: "10315", state: "APPROVED_LOCKED"}
];

const res = data.filter(({ state }) => state.includes("LOCKED"));

console.log(res);
 

.as-console-wrapper { max-height: 100% !important; top: auto; }

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.