1

Working in d3.js, my data is something like this (but much longer):

var all = [{
"tp_ot_avg": 0.003,
"tp_ot_s": 24.7,
"tp_overlap_pc_s": 45.7,
"tp_ot_avg_s": 0.005,
"sw_adult": 74,
"sw_overlap": 6,
"sw_child": 7,
"sw_pause": 13
}];

I want to filter it by key name; the desired output is this:

var data = {
"sw_adult": 74,
"sw_overlap": 6,
"sw_child": 7,
"sw_pause": 13
};

So far, nothing I've tried has worked!

ATTEMPT 1:

var data = all.filter(function (a) {
  return (
    a.key == "sw_adult" ||
    a.key == "sw_child" ||
    a.key == "sw_overlap" ||
    a.key == "sw_pause"
  );
});

ATTEMPT 2:

tokeep = ["sw_adult", "sw_child", "sw_overlap", "sw_pause"]
var data = all.filter(function(d,i){ return tokeep.indexOf(d.key) >= 0 })

ATTEMPT 3:

var data = d3.selectAll("all").filter(
    all.key == "sw_adult" ||
    all.key == "sw_child" ||
    all.key == "sw_overlap" ||
    all.key == "sw_pause"
  );

What am I doing wrong?

0

3 Answers 3

1

If your all array contain's only one object then you can use simply do this way.

const keys = ["sw_adult", "sw_overlap", "sw_child", "sw_pause"];
const all = [{
  "tp_ot_avg": 0.003,
  "tp_ot_s": 24.7,
  "tp_overlap_pc_s": 45.7,
  "tp_ot_avg_s": 0.005,
  "sw_adult": 74,
  "sw_overlap": 6,
  "sw_child": 7,
  "sw_pause": 13
}];

const output = Object.keys(all[0]).reduce((result, current) => {
  if (keys.includes(current)) {
    result[current] = all[0][current];
  }
  return result;
}, {});
console.log(output);

And It's any chance that all array can have multiple object then you can do this way.

const keys = ["sw_adult", "sw_overlap", "sw_child", "sw_pause"];
const all = [{
  "tp_ot_avg": 0.003,
  "tp_ot_s": 24.7,
  "tp_overlap_pc_s": 45.7,
  "tp_ot_avg_s": 0.005,
  "sw_adult": 74,
  "sw_overlap": 6,
  "sw_child": 7,
  "sw_pause": 13
}, {
  "tp_ot_avg": 0.003,
  "tp_ot_s": 24.7,
  "tp_overlap_pc_s": 45.7,
  "tp_ot_avg_s": 0.005,
  "sw_adult": 742,
  "sw_overlap": 62,
  "sw_child": 72,
  "sw_pause": 132
}];

const output = all.map((a) => Object.keys(a).reduce((result, current) => {
  if (keys.includes(current)) {
    result[current] = a[current];
  }
  return result;
}, {}));
console.log(output);

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

Comments

1

You were in the right direction, just filter the keys that you need.

Iterate through the all array, in every iteration check for its entries using Object.entries whether the current object has the keys or not, if it has extract it using Object.fromEntries and break the flow once you found your desired object.

var all = [{
    "tp_ot_avg": 0.003,
    "tp_ot_s": 24.7,
    "tp_overlap_pc_s": 45.7,
    "tp_ot_avg_s": 0.005,
    "sw_adult": 74,
    "sw_overlap": 6,
    "sw_child": 7,
    "sw_pause": 13
  },
  {
    "tp_ot_avg": 0.003,
    "tp_ot_s": 24.7,
    "tp_overlap_pc_s": 45.7,
    "tp_ot_avg_s": 0.005
  }
];

const keys = ['sw_adult', 'sw_overlap', 'sw_child', 'sw_pause'];
let resObj;

for (const item of all) {
  const filteredEntries = Object.entries(item).filter(([key, value]) => keys.includes(key));
  if (filteredEntries.length) {
    resObj = Object.fromEntries(filteredEntries);
    break;
  }
}

console.log(resObj);

1 Comment

This is so helpful, thank you! It's still not working quite right for me - I think because I was trying to get an object ({...}), and I believe this returns an array([...])? Do you know how I would get this data as an object?
0

The attempts made are to filter the array object, not the object keys. Try:

var all = [{
  "tp_ot_avg": 0.003,
  "tp_ot_s": 24.7,
  "tp_overlap_pc_s": 45.7,
  "tp_ot_avg_s": 0.005,
  "sw_adult": 74,
  "sw_overlap": 6,
  "sw_child": 7,
  "sw_pause": 13
}];


// destruct the properties and return a new object
const output = all.map(({
  sw_adult,
  sw_child,
  sw_overlap,
  sw_pause
}) => ({
  sw_adult,
  sw_child,
  sw_overlap,
  sw_pause
}))

// Shorter and uses a list of keys to pick
const keys = ["sw_adult","sw_overlap","sw_child","sw_pause"];
// return a new object from merging objects created by { key: value }
const output2 = all.map(o =>
   Object.assign({}, ...keys.map(k => ({ [k]: o[k] })))
);

console.log(output2);

1 Comment

Thank you for this! It's still not working quite right for me - I think because I was trying to get an object ({...}), and I believe this returns an array([...])? Do you know how I would get this data as an object?

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.