简体   繁体   English

JavaScript - 通过深度嵌套的 object 键从标准数组中过滤 Object?

[英]JavaScript - Filter Object from criteria array, by deeply nested object key?

I have been breaking my head the last few days trying to implement the following functionality:过去几天我一直在努力实现以下功能:

I have an incoming object, with a nested sub-object that's a list of dates.我有一个传入的 object,它有一个嵌套的子对象,它是一个日期列表。 I would like to filter the original object against a range of dates, and return the modified filtered object, with only the specified dates.我想根据一系列日期过滤原始 object,并返回修改后的过滤 object,仅包含指定的日期。

Here is the desired functionality:这是所需的功能:

let incomingObject = {
    'one': {
        id: "one",
        dates: {
            "2021-05-01": [{ a: "foo", b: "bar" }],
            "2021-05-02": [{ a: "foo", b: "bar" }] } },
    'two': {
        id: "two",
        dates: {
            "2021-05-01": [{ a: "foo", b: "bar" }, { a: "foo2", b: "bar2" }],
            "2021-05-02": [{ a: "baz", b: "far" }] } },
    'three': {
        id: "three",
        dates: {
            "2021-05-03": [{ a: "foo", b: "bar" }],
            "2021-05-02": [{ a: "foo", b: "bar" }] } } };

// Function to get an array between two dates
const getDaysArray = function (s, e) {
    for (var a = [], d = new Date(s); d <= new Date(e); d.setDate(d.getDate() + 1)) {
        a.push(new Date(d));
    }
    let aStrings = a.map((date) => date.toISOString().slice(0, 10));
    return aStrings;
};

I have no idea how to implement this function, that would return the "filtered" object:我不知道如何实现这个 function,它将返回“过滤”的 object:

filterResults(incomingObject, getDaysArray("2021-05-01", "2021-05-01"));

This is the desired result - all the (sub-)objects that don't pass the filter, are left out:这是期望的结果 - 所有未通过过滤器的(子)对象都被排除在外:

let desiredResult = {
    'one': {
        id: "one",
        dates: {
            "2021-05-01": [{ a: "foo", b: "bar" }] } },
    'two': {
        id: "two",
        dates: {
            "2021-05-01": [{ a: "foo", b: "bar" }, { a: "foo2", b: "bar2" }] } } };

And my progress so far:到目前为止我的进展:

let dateRange = getDaysArray("2021-05-01", "2021-05-01");

// This logs out only the required keys –– however, logging out the whole "parent" object is completely beyond my comprehension at the moment...
const filteredImages = Object.keys(images).forEach((key) => {
    let imgObject = images[key];
    Object.keys(images[key].dates).forEach((key) => {
        if (dateRange.includes(key)) {
            console.log(key);
        }
    });
});

All help or pointers much appreciated!非常感谢所有帮助或指示!

 const incomingObject={one:{id:"one",dates:{"2021-05-01":[{a:"foo",b:"bar"}],"2021-05-02":[{a:"foo",b:"bar"}]}},two:{id:"two",dates:{"2021-05-01":[{a:"foo",b:"bar"},{a:"foo2",b:"bar2"}],"2021-05-02":[{a:"baz",b:"far"}]}},three:{id:"three",dates:{"2021-05-03":[{a:"foo",b:"bar"}],"2021-05-02":[{a:"foo",b:"bar"}]}}}; const getDaysArray = function(e,t){for(var a=[],n=new Date(e);n<=new Date(t);n.setDate(n.getDate()+1))a.push(new Date(n));return a.map(e=>e.toISOString().slice(0,10))} const filterResults = (data, days) => Object.entries(data).reduce((result, [k, v]) => { const {dates, ...rest} = v const filteredDates = days.reduce((acc, date) => { if(v.dates[date]) acc[date] = v.dates[date] return acc }, {}) if (Object.keys(filteredDates).length) result.push([k, {...rest, dates: filteredDates }]) return result }, []) const res = filterResults( incomingObject, getDaysArray("2021-05-01", "2021-05-01") ) console.log(Object.fromEntries(res))
 .as-console-wrapper { max-height: 100%;important: top; 0; }

What about this one?这个如何? I find it very concise and modern:我觉得它非常简洁和现代:

const filterResults = (data, days) => 
  Object.entries(data).reduce((acc, [n, { id, dates }]) => {
    const ds = Object.entries(dates).filter(([d,]) => days.includes(d))
    return ds.length ? { ...acc, [n]: { id, dates: Object.fromEntries(ds) } } : acc
  }, {})

The nice thing here is to use nested destructuring patterns and spread operator to avoid boilerplate code.这里的好处是使用嵌套解构模式和扩展运算符来避免样板代码。

Also, while doing reduce over Object.entries , we can construct an object directly, without need of an intermediary array.此外,在对Object.entries进行reduce的同时,我们可以直接构造一个 object,而无需中间数组。 In this implementation, everything is done in just one iteration over the original data array, so it performs better.在这个实现中,一切都在原始data数组的一次迭代中完成,因此它的性能更好。


Additional information on the techniques used in the snippet:有关片段中使用的技术的其他信息:

You can use the array methods filter()您可以使用数组方法filter()

In your case it could look something like this:在您的情况下,它可能看起来像这样:

 const incoming = [ { nested: { date: '2021-05-01' } }, { nested: { date: '2021-03-16' } }, { nested: { date: '2021-02-05' } }, { nested: { date: '2021-01-20' } }, ] let someRange = ['2021-02-05', '2021-03-24'] const result = incoming.filter((item) => { return item.nested.date >= someRange[0] && item.nested.date <= someRange[1] }) console.log(result)

You need to transform your object into an array with Object.values(yourArray) to use the filter() method.您需要使用filter()方法将 object 转换为具有Object.values(yourArray)的数组。

EDIT:编辑:

Just read your post again.再看一遍你的帖子。 You can use the Object.keys() to retrieve the keys from your object like so:您可以使用Object.keys()从 object 中检索密钥,如下所示:

 const dates = { "2021-05-01": [{ a: "foo", b: "bar", }, { a: "foo2", b: "bar2", }, ], "2021-05-02": [{ a: "baz", b: "far", }, ], } const dateKeys = Object.keys(dates) console.log(`Keys from date object: ${dateKeys}`) const result = dateKeys.filter((item) => { return item >= '2021-05-02' }) console.log(result)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用javascript中的值数组过滤深度嵌套的对象数组 - filter through deeply nested object array with array of values in javascript 在深层嵌套的对象数组中搜索单个键 - Searching deeply nested object array for a single key 使用 JavaScript 将深度嵌套对象中的值打印为数组 - Printing values from a deeply nested object as an array using JavaScript 如何从具有 Javascript 的值数组中获取深度嵌套的 object 结构 - How to get deeply nested object structure from array of values with Javascript 在javascript数组中查找和修改深度嵌套的对象 - find and modify deeply nested object in javascript array javascript中数组与深度嵌套对象的交集 - Intersection of an array with a deeply nested object in javascript 如果存在键名数组,则更改对象的深层嵌套键值 - Change deeply nested key value of an object if there's an array of key names Javascript:在JavaScript中从另一个对象创建一个深度嵌套的对象 - Javascript: create a deeply nested object in javascript from another object 返回与深度嵌套的 Javascript 对象中的搜索键对应的值 - Returning value corresponding to a searched key in a deeply nested Javascript object Javascript:递归问题 --&gt; 返回深度嵌套对象中最长的键值 - Javascript: Recursion Problem --> Return the longest key value in a deeply nested object
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM