4

Here is the code in question:

const posts = [{
  data: {
    id: 1,
    date: "2019-02-03",
    ev_filter_1: ["art", "foodie"],
    ev_filter_2: ["value1", "value2"],
    ev_filter_3: ["value1", "value2"],
    ev_filter_4: ["all", "12+"]
  }
},
  {
    data: {
      id: 2,
      date: "",
      ev_filter_1: ["arti", "foodie"],
      ev_filter_2: ["value1", "value2"],
      ev_filter_3: ["value1", "value2"],
      ev_filter_4: ["all", "19+"]
    }
  },
  {
    data: {
      id: 3,
      date: "2019-02-03",
      ev_filter_1: ["art", "foodie"],
      ev_filter_2: ["value1", "value75"],
      ev_filter_3: ["value1", "value2"],
      ev_filter_4: ["all", "12+"]
    }
  }
];

function sift2(arrObjLit, pattern, ...values) {
  const toMatch = new Set(values)
  const result = arrObjLit.map(o => o.data)
  .filter(o =>
      Object.entries(o)
      .filter(([k, v]) => {
        console.log(`${k}: ${v}`)
        return true
      })
      .filter(([k, v]) => k.startsWith(pattern))
      .filter(([k, v]) => Array.isArray(v))
      .filter(([k, v]) => toMatch.has(v))
          .length > 0
  )
  return result;
}

console.log(...sift2(posts, "ev_", "value75", "12+"));

Which is baffling me. Based on this post I would expect the array destructing in filter to be wrong. And yet, it's not. It's exactly what I am looking for. Why would the destructing be flat in the filter method? Am I observing things wrong?

.filter(o =>
      Object.entries(o)
      .filter(([k, v]) => k.startsWith(pattern))
2
  • 1
    What do you mean by "the destructuring be flat"? Commented Jul 11, 2017 at 6:21
  • toMatch.has(v) doesn't work when toMatch is a set of strings and v is an array. Commented Jul 11, 2017 at 6:34

1 Answer 1

3

Because you are now properly nesting the iterations, calling the second filter directly on the output of entries. Notice that you are using

.filter(o => Object.entries(o).filter(…).… )

instead of

.map(Object.entries).filter(o => o.… )

That said, I'd rewrite your function to

function sift2(arrObjLit, pattern, ...values) {
  const toMatch = new Set(values)
  return arrObjLit.filter(o =>
    Object.entries(o.data)
    .some(([k, v]) => {
      console.log(`${k}: ${v}`);
      return k.startsWith(pattern)
          && Array.isArray(v)
          && v.some(x => toMatch.has(x));
    })
  );
}
Sign up to request clarification or add additional context in comments.

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.