Data Mastery
Data Mastery

Reputation: 2085

Filter an object with multiple arrays based on value of one array

This is how my dataset looks like:

const data = {
    "VS_factor": [
      "FA1_n",
      "FA1_y",
      "FA2_n"
    ],
    "coord.Dim.1": [
      -0.232849099744328,
      0.875136458459595,
      -0.0810629616429348,

    ],
    "coord.Dim.2": [
      0.0223397885030092,
      -0.0839615159119212,
      -0.334981738274959,

    ],
    "cluster": [
      0,
      5,
      0,
    ]
  }

I want to filter the object and every array inside based the value of the last variable. In this example I only want to keep the values where cluster" === 5.

const desired = {
    "VS_factor": [
        "FA1_y",
      ],
      "coord.Dim.1": [
        0.875136458459595,
  
      ],
      "coord.Dim.2": [
        -0.0839615159119212,
  
      ],
      "cluster": [
        5,
      ]
}

I have trouble with this since I can not use .filter on an Object. Does anyone know a solution how to archieve my desired result?

Upvotes: 0

Views: 213

Answers (4)

Sascha A.
Sascha A.

Reputation: 4616

Get the index from the cluster, check if it's found otherwise return object without data. Iterate over Object.values with this index and push the new entries to the properties-arrays.

const data = {
  VS_factor: ["FA1_n", "FA1_y", "FA2_n"],
  "coord.Dim.1": [-0.232849099744328, 0.875136458459595, -0.0810629616429348],
  "coord.Dim.2": [0.0223397885030092, -0.0839615159119212, -0.334981738274959],
  cluster: [0, 5, 0],
};

function filterClusterId(id, data) {
    let ind = data.cluster.indexOf(id);
    let result = {VS_factor: [], "coord.Dim.1": [], "coord.Dim.2": [], cluster: []};
    if (ind===-1) return result;

    Object.entries(data).forEach(([key,value]) => {
        result[key].push(value[ind]);
    })
    return result;
}
  
console.log(filterClusterId(5, data));

Upvotes: 0

gbalduzzi
gbalduzzi

Reputation: 10166

I would define a filter function that takes three arguments: the key to filter on, and the value desired, and the data object

const filterData = (key, value, data) => {

  const result = {}
  
  for (let i = 0; i < data[key].length; i++) {
    if (data[key][i] === value) { // found the desired Index
    
       Object.entries(data).forEach(([dataKey, dataArr]) => {
         if (!result[dataKey]) {
            result[dataKey] = []
         }
         result[dataKey].push(dataArr[i])
       })
    }
  }

  return result
}

This function will work on different keys and will also extract multiple 'records' in there are multiple elements with the target value (e.g. there are 2 records with cluster equal to 5.

Some assumption made by the code, add some checks if they are not valid:

  • The arrays only contain primitive values, to it's safe to check equality with ===.
  • All keys in the original data have an array has value with the same number of entries
  • The key passed as argument actually exists in the data

Upvotes: 0

hgb123
hgb123

Reputation: 14871

You could get the expected index and then filter

const data = {
  VS_factor: ["FA1_n", "FA1_y", "FA2_n"],
  "coord.Dim.1": [-0.232849099744328, 0.875136458459595, -0.0810629616429348],
  "coord.Dim.2": [0.0223397885030092, -0.0839615159119212, -0.334981738274959],
  cluster: [0, 5, 0],
}

const expectedIndex = data.cluster.findIndex((c) => c === 5)

const res = Object.fromEntries(
  Object.entries(data).map(([key, value]) => [key, [value[expectedIndex]]])
)

console.log(res)

Upvotes: 1

Ele
Ele

Reputation: 33726

Assuming you want to filter those elements which are not at a specific index (index where cluster === 5).

const data = {    "VS_factor": [      "FA1_n",      "FA1_y",      "FA2_n"    ],    "coord.Dim.1": [      -0.232849099744328,      0.875136458459595,      -0.0810629616429348,    ],    "coord.Dim.2": [      0.0223397885030092,      -0.0839615159119212,      -0.334981738274959,    ],    "cluster": [      0,      5,      0,    ]  },
      targetCluster = 5,
      targetIndex = data.cluster.findIndex(c => c === targetCluster),
      result = Object.entries(data).map(([key, array]) => ({[key]: [array[targetIndex]]}));
  
console.log(result);

Upvotes: 0

Related Questions