1

I have an array in the format coming out of d3js treemap using the node.path(target) on every node

var arr = [[{data: A},{data: B},{data: C}],
           [{data: C},{data: B},{data: A}],
           [{data: B},{data: D},{data: A}],
           [{data: A},{data: D},{data: B}]
          ]

I would like to filter the array to remove the reverse paths i.e [{data: C},{data: B},{data: A}] is the reverse of [{data: A},{data: B},{data: C}] so only [{data: A},{data: B},{data: C}] should be kept.

Thus final array should look like:

var finalarr = [[{data: A},{data: B},{data: C}],
                [{data: B},{data: D},{data: A}],
               ]

I have tried doing a simple reverse comparison.

function removereversepaths(arr){
 var cleanpaths = [];

 arr.forEach((a) => {
  var arev = [...a].reverse();
  if (!cleanpaths.includes(arev)){
   cleanpaths.push(a);
  } 
 });
}

I am wondering if I can write a filter function to perform this but for some reason I am drawing a blank on how to check the new array in the filter function for the reverse array. Any help/direction is appreciated. Thanks in advance.

3
  • 1
    do you have only one property in the objects? Commented Mar 1, 2019 at 19:15
  • Can you show an example real or obfuscated data? The structure of the {data: X} should help us provide an answer. Commented Mar 1, 2019 at 19:19
  • @Barthy the data is actually like [{data: A, value: '123'},{data: B, value: '213'},{data: C, value: '530'}] for example. I simplified it because I only need to filter by the data field. Commented Mar 1, 2019 at 20:31

1 Answer 1

3

You could use the filterd array as result and for lookup.

This solution takes takes data property for comparing and if the array is in reversed order, this array is filtered out.

To check if the array already exists in the filtered array, this array is iterated and checked with each element from the last to the first element and exit early if one array is found with objects with the same values.

const compare = (a, b) => a.data === b.data; // or what ever suits

var array = [[{ data: 'A' }, { data: 'B' }, { data: 'C' }], [{ data: 'C' }, { data: 'B' }, { data: 'A' }], [{ data: 'B' }, { data: 'D' }, { data: 'A' }], [{ data: 'A' }, { data: 'D' }, { data: 'B' }]],
    filtered = [];

array.filter(a => {
    if (filtered.some(t => a.every((o, i, { length }) => compare(t[length - 1 - i], o)))) {
        return;
    }
    filtered.push(a);
});

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

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

1 Comment

Thanks for the solution. Could you add a more detailed explanation of the code just for my understanding.

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.