1

I am trying to filter a large multi dimensional array, I know I can re build the array but I was wondering if there was a way of me filtering this array based on if the key "d" contains "d3.1"

   const arr = [
        {a:"a1",b:"b1",c:[{d:"d1.1",e:"e1.1"},{d:"d1.2",e:"e1.2"}]},
        {a:"a2",b:"b2",c:[{d:"d2.1",e:"e2.1"},{d:"d2.2",e:"e2.2"}]},
        {a:"a3",b:"b3",c:[{d:"d3.1",e:"e3.1"},{d:"d3.2",e:"e3.2"}]},
        {a:"a4",b:"b4",c:[{d:"d4.1",e:"e4.1"},{d:"d4.2",e:"e4.2"}]},
        {a:"a1",b:"b1",c:[{d:"d1.1",e:"e1.1"},{d:"d3.1",e:"e1.2"}]},
        {a:"a5",b:"b5",c:[{d:"d3.1",e:"e3.1"},{d:"d3.2",e:"e3.2"}]}
    ]

I have tried using .some and .filter but as it's an object within an array of objects I can't seem to get it to work.

My required output would be to have all objects where d contains "d3.1" for example:

output:

    [
       {a:"a3",b:"b3",c:[{d:"d3.1",e:"e3.1"},{d:"d3.2",e:"e3.2"}]},
       {a:"a1",b:"b1",c:[{d:"d1.1",e:"e1.1"},{d:"d3.1",e:"e1.2"}]},
       {a:"a5",b:"b5",c:[{d:"d3.1",e:"e3.1"},{d:"d3.2",e:"e3.2"}]}
    ]
3
  • @CBroe I said what I tired? And that I also realised it wasn't a possible solution and wasn't sure if there was a solution for this issue that I didn't know of. Why would I show something doesn't and wouldn't work? Seems illogical. Commented Sep 20, 2022 at 13:18
  • "I said what I tired" - but in a very unspecific way. Don't give us "prose" verbally describing what you did - show the actual code. "And that I also realised it wasn't a possible solution" - realized wrong to begin with, as one of the answers you gotten shows ... Commented Sep 20, 2022 at 13:33
  • @CBroe okay, It seemed nonsensical to post something I knew wasn't working. Adding something that wasn't working vs not, clearly wouldn't have change the outcome. I learnt something without adding it, plus it allowed for more open answers/solutions that don't focus purely on the example given. Commented Sep 20, 2022 at 19:06

4 Answers 4

2

Here is a quick solution:

const arr = [
            {a:"a1",b:"b1",c:[{d:"d1.1",e:"e1.1"},{d:"d1.2",e:"e1.2"}]},
            {a:"a2",b:"b2",c:[{d:"d2.1",e:"e2.1"},{d:"d2.2",e:"e2.2"}]},
            {a:"a3",b:"b3",c:[{d:"d3.1",e:"e3.1"},{d:"d3.2",e:"e3.2"}]},
            {a:"a4",b:"b4",c:[{d:"d4.1",e:"e4.1"},{d:"d4.2",e:"e4.2"}]},
            {a:"a1",b:"b1",c:[{d:"d1.1",e:"e1.1"},{d:"d3.1",e:"e1.2"}]},
            {a:"a5",b:"b5",c:[{d:"d3.1",e:"e3.1"},{d:"d3.2",e:"e3.2"}]}
    ]
    
    
console.log(arr.filter(el => JSON.stringify(el).includes("d3.1")))

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

Comments

1

If you want to filter the array for elements with property c containing at least one element (i.e. .some(...)) with property d being equal to "d3.1" you can use this solution:

const arr = [
        {a:"a1",b:"b1",c:[{d:"d1.1",e:"e1.1"},{d:"d1.2",e:"e1.2"}]},
        {a:"a2",b:"b2",c:[{d:"d2.1",e:"e2.1"},{d:"d2.2",e:"e2.2"}]},
        {a:"a3",b:"b3",c:[{d:"d3.1",e:"e3.1"},{d:"d3.2",e:"e3.2"}]},
        {a:"a4",b:"b4",c:[{d:"d4.1",e:"e4.1"},{d:"d4.2",e:"e4.2"}]},
        {a:"a1",b:"b1",c:[{d:"d1.1",e:"e1.1"},{d:"d3.1",e:"e1.2"}]},
        {a:"a5",b:"b5",c:[{d:"d3.1",e:"e3.1"},{d:"d3.2",e:"e3.2"}]}
    ]
 
 const filtered = arr.filter(e => e.c.some(x => x.d == "d3.1"))
 
 console.log(filtered)

Otherwise, please specify your requirements closer...

Comments

1

You could use a recursive approach to find matching array elements, creating a function like findMatch() that accepts a customizable predicate function.

This function could return true for exact matches or use regex expressions etc.

We'd then using this with Array.filter() to return the required result.

const arr = [ {a:"a1",b:"b1",c:[{d:"d1.1",e:"e1.1"},{d:"d1.2",e:"e1.2"}]}, {a:"a2",b:"b2",c:[{d:"d2.1",e:"e2.1"},{d:"d2.2",e:"e2.2"}]}, {a:"a3",b:"b3",c:[{d:"d3.1",e:"e3.1"},{d:"d3.2",e:"e3.2"}]}, {a:"a4",b:"b4",c:[{d:"d4.1",e:"e4.1"},{d:"d4.2",e:"e4.2"}]}, {a:"a1",b:"b1",c:[{d:"d1.1",e:"e1.1"},{d:"d3.1",e:"e1.2"}]}, {a:"a5",b:"b5",c:[{d:"d3.1",e:"e3.1"},{d:"d3.2",e:"e3.2"}]} ]

function findMatch(obj, predicate) {
    for(let k in obj) {
        if (obj[k] && typeof(obj[k]) === 'object') {
           if (findMatch(obj[k], predicate)) return true;
        } else if (predicate(k, obj[k])) {
            return true;
        }
    }
}

// Custom predicate, change as needed.
const predicate = (key, value) => key === 'd' && value === 'd3.1';
const result = arr.filter(el => findMatch(el, predicate));
console.log('Result:');
result.forEach(el => console.log(JSON.stringify(el)));
.as-console-wrapper { max-height: 100% !important; }

Comments

0

You can use nested foreach to get your desired output, I have consoled both array(one containing the output you want and the other containing the indexes of those outputs)

values_ar = [];
index_ar = [];
arr.forEach((items, indexs)=>{
    const test = arr[indexs].c;
    test.forEach((item, index)=>{
        if(test[index].d == "d3.1"){
            values_ar.push(items)
            index_ar.push(indexs)
        }
    })
})
console.log(values_ar)
console.log(index_ar)

Hope that answers your question.

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.