简体   繁体   中英

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?

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)

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);

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 (eg 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

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));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM