使用检查属性的子数组在数组中查找对象 [英] Find object in array with subarray checking an property

查看:91
本文介绍了使用检查属性的子数组在数组中查找对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在下面有一个数组,每个元素都有另一个名为FunctionalityChildren的数组,我需要找到包含属性 ActionFull 的唯一对象,该属性等于一个变量,例如'/budget/allocation'或'/预算"

I have the array below and each element has another array called FunctionalityChildren, I need find the unique object that contains the property ActionFull equal a variable, for example '/budget/allocation' or '/budget'

let bigArray = [
      {
        "FunctionalityID": 114,
        "Name": "General Register",
        "Action": "/general-register",
        "Icon": "settings_input_composite",
        "System_ID": 21,
        "FunctionalityFather_ID": null,
        "Active": 1,
        "Priority": 1,
        "FunctionalityChildren": [
          {
            "FunctionalityID": 115,
            "Name": "Supplier",
            "Action": "/supplier",
            "Icon": "perm_contact_calendar",
            "System_ID": 21,
            "FunctionalityFather_ID": 114,
            "Active": 1,
            "Priority": 1,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1251,
                "Profile_ID": 68,
                "Functionality_ID": 115,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/general-register/supplier"
          },
          {
            "FunctionalityID": 116,
            "Name": "RPA",
            "Action": "/rpa",
            "Icon": "view_day",
            "System_ID": 21,
            "FunctionalityFather_ID": 114,
            "Active": 1,
            "Priority": 2,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1252,
                "Profile_ID": 68,
                "Functionality_ID": 116,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/general-register/rpa"
          },
          {
            "FunctionalityID": 117,
            "Name": "Cost Center",
            "Action": "/cost-center",
            "Icon": "home",
            "System_ID": 21,
            "FunctionalityFather_ID": 114,
            "Active": 1,
            "Priority": 3,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1253,
                "Profile_ID": 68,
                "Functionality_ID": 117,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/general-register/cost-center"
          },
          {
            "FunctionalityID": 118,
            "Name": "Departament",
            "Action": "/departament",
            "Icon": "donut_small",
            "System_ID": 21,
            "FunctionalityFather_ID": 114,
            "Active": 1,
            "Priority": 4,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1254,
                "Profile_ID": 68,
                "Functionality_ID": 118,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/general-register/departament"
          },
          {
            "FunctionalityID": 119,
            "Name": "Product Line",
            "Action": "/product-line",
            "Icon": "view_headline",
            "System_ID": 21,
            "FunctionalityFather_ID": 114,
            "Active": 1,
            "Priority": 5,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1255,
                "Profile_ID": 68,
                "Functionality_ID": 119,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/general-register/product-line"
          },
          {
            "FunctionalityID": 120,
            "Name": "Product",
            "Action": "/product",
            "Icon": "shopping_cart",
            "System_ID": 21,
            "FunctionalityFather_ID": 114,
            "Active": 1,
            "Priority": 6,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1256,
                "Profile_ID": 68,
                "Functionality_ID": 120,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/general-register/product"
          }
        ],
        "ProfileFunctionalities": [
          {
            "ProfileFunctionalityID": 1250,
            "Profile_ID": 68,
            "Functionality_ID": 114,
            "CanInsert": false,
            "CanUpdate": false,
            "CanDelete": false
          }
        ],
        "ActionFull": "/general-register",
        "HasFunctionalities": true,
        "model": false
      },
      {
        "FunctionalityID": 99,
        "Name": "Budget Account",
        "Action": "/budget-account",
        "Icon": "monetization_on",
        "System_ID": 21,
        "FunctionalityFather_ID": null,
        "Active": 1,
        "Priority": 2,
        "FunctionalityChildren": [
          {
            "FunctionalityID": 100,
            "Name": "Sector",
            "Action": "/sector",
            "Icon": "account_balance",
            "System_ID": 21,
            "FunctionalityFather_ID": 99,
            "Active": 1,
            "Priority": 1,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1258,
                "Profile_ID": 68,
                "Functionality_ID": 100,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/budget-account/sector"
          },
          {
            "FunctionalityID": 101,
            "Name": "Group",
            "Action": "/group",
            "Icon": "group_work",
            "System_ID": 21,
            "FunctionalityFather_ID": 99,
            "Active": 1,
            "Priority": 2,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1259,
                "Profile_ID": 68,
                "Functionality_ID": 101,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/budget-account/group"
          },
          {
            "FunctionalityID": 102,
            "Name": "Account",
            "Action": "/account",
            "Icon": "attach_money",
            "System_ID": 21,
            "FunctionalityFather_ID": 99,
            "Active": 1,
            "Priority": 3,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1260,
                "Profile_ID": 68,
                "Functionality_ID": 102,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/budget-account/account"
          },
          {
            "FunctionalityID": 103,
            "Name": "Budget",
            "Action": "/budget",
            "Icon": "credit_card",
            "System_ID": 21,
            "FunctionalityFather_ID": 99,
            "Active": 1,
            "Priority": 4,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1261,
                "Profile_ID": 68,
                "Functionality_ID": 103,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/budget-account/budget"
          }
        ],
        "ProfileFunctionalities": [
          {
            "ProfileFunctionalityID": 1257,
            "Profile_ID": 68,
            "Functionality_ID": 99,
            "CanInsert": false,
            "CanUpdate": false,
            "CanDelete": false
          }
        ],
        "ActionFull": "/budget-account",
        "HasFunctionalities": true,
        "model": false
      },
      {
        "FunctionalityID": 105,
        "Name": "Budget",
        "Action": "/budget",
        "Icon": "credit_card",
        "System_ID": 21,
        "FunctionalityFather_ID": null,
        "Active": 1,
        "Priority": 3,
        "FunctionalityChildren": [
          {
            "FunctionalityID": 106,
            "Name": "Allocation",
            "Action": "/allocation",
            "Icon": "note_add",
            "System_ID": 21,
            "FunctionalityFather_ID": 105,
            "Active": 1,
            "Priority": 1,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1272,
                "Profile_ID": 68,
                "Functionality_ID": 106,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/budget/allocation"
          },
          {
            "FunctionalityID": 107,
            "Name": "Copy",
            "Action": "/copy",
            "Icon": "content_copy",
            "System_ID": 21,
            "FunctionalityFather_ID": 105,
            "Active": 1,
            "Priority": 2,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1273,
                "Profile_ID": 68,
                "Functionality_ID": 107,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/budget/copy"
          },
          {
            "FunctionalityID": 108,
            "Name": "In And Out",
            "Action": "/in-and-out",
            "Icon": "swap_vertical_circle",
            "System_ID": 21,
            "FunctionalityFather_ID": 105,
            "Active": 1,
            "Priority": 3,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1274,
                "Profile_ID": 68,
                "Functionality_ID": 108,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/budget/in-and-out"
          },
          {
            "FunctionalityID": 109,
            "Name": "Account Accounting",
            "Action": "/account-accounting",
            "Icon": "assignment",
            "System_ID": 21,
            "FunctionalityFather_ID": 105,
            "Active": 1,
            "Priority": 4,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1275,
                "Profile_ID": 68,
                "Functionality_ID": 109,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/budget/account-accounting"
          },
          {
            "FunctionalityID": 110,
            "Name": "Event",
            "Action": "/eventos",
            "Icon": "shopping_cart",
            "System_ID": 21,
            "FunctionalityFather_ID": 105,
            "Active": 1,
            "Priority": 5,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1276,
                "Profile_ID": 68,
                "Functionality_ID": 110,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/budget/eventos"
          },
          {
            "FunctionalityID": 111,
            "Name": "Copy Counter",
            "Action": "/copy-counter",
            "Icon": "swap_vertical_circle",
            "System_ID": 21,
            "FunctionalityFather_ID": 105,
            "Active": 1,
            "Priority": 6,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1277,
                "Profile_ID": 68,
                "Functionality_ID": 111,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/budget/copy-counter"
          }
        ],
        "ProfileFunctionalities": [
          {
            "ProfileFunctionalityID": 1271,
            "Profile_ID": 68,
            "Functionality_ID": 105,
            "CanInsert": false,
            "CanUpdate": false,
            "CanDelete": false
          }
        ],
        "ActionFull": "/budget",
        "HasFunctionalities": false,
        "model": false
      },
      {
        "FunctionalityID": 112,
        "Name": "Config",
        "Action": "/config",
        "Icon": "build",
        "System_ID": 21,
        "FunctionalityFather_ID": null,
        "Active": 1,
        "Priority": 4,
        "FunctionalityChildren": [
          {
            "FunctionalityID": 113,
            "Name": "Control Year Month",
            "Action": "/control-year-month",
            "Icon": "date_range",
            "System_ID": 21,
            "FunctionalityFather_ID": 112,
            "Active": 1,
            "Priority": 1,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1263,
                "Profile_ID": 68,
                "Functionality_ID": 113,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/config/control-year-month"
          }
        ],
        "ProfileFunctionalities": [
          {
            "ProfileFunctionalityID": 1262,
            "Profile_ID": 68,
            "Functionality_ID": 112,
            "CanInsert": false,
            "CanUpdate": false,
            "CanDelete": false
          }
        ],
        "ActionFull": "/config",
        "HasFunctionalities": true,
        "model": false
      },
      {
        "FunctionalityID": 121,
        "Name": "Report",
        "Action": "/report",
        "Icon": "picture_as_pdf",
        "System_ID": 21,
        "FunctionalityFather_ID": null,
        "Active": 1,
        "Priority": 5,
        "FunctionalityChildren": [
          {
            "FunctionalityID": 122,
            "Name": "Report 1",
            "Action": "/report-um",
            "Icon": "picture_as_pdf",
            "System_ID": 21,
            "FunctionalityFather_ID": 121,
            "Active": 1,
            "Priority": 1,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1265,
                "Profile_ID": 68,
                "Functionality_ID": 122,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/report/report-um"
          },
          {
            "FunctionalityID": 123,
            "Name": "Report 2",
            "Action": "/report-dois",
            "Icon": "picture_as_pdf",
            "System_ID": 21,
            "FunctionalityFather_ID": 121,
            "Active": 1,
            "Priority": 2,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1266,
                "Profile_ID": 68,
                "Functionality_ID": 123,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/report/report-dois"
          },
          {
            "FunctionalityID": 124,
            "Name": "Report 3",
            "Action": "/report-tres",
            "Icon": "picture_as_pdf",
            "System_ID": 21,
            "FunctionalityFather_ID": 121,
            "Active": 1,
            "Priority": 3,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1267,
                "Profile_ID": 68,
                "Functionality_ID": 124,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/report/report-tres"
          }
        ],
        "ProfileFunctionalities": [
          {
            "ProfileFunctionalityID": 1264,
            "Profile_ID": 68,
            "Functionality_ID": 121,
            "CanInsert": false,
            "CanUpdate": false,
            "CanDelete": false
          }
        ],
        "ActionFull": "/report",
        "HasFunctionalities": true,
        "model": false
      },
      {
        "FunctionalityID": 125,
        "Name": "Profile",
        "Action": "/profile",
        "Icon": "person",
        "System_ID": 21,
        "FunctionalityFather_ID": null,
        "Active": 1,
        "Priority": 6,
        "FunctionalityChildren": [
          {
            "FunctionalityID": 126,
            "Name": "New",
            "Action": "/new",
            "Icon": "plus_one",
            "System_ID": 21,
            "FunctionalityFather_ID": 125,
            "Active": 1,
            "Priority": 1,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1269,
                "Profile_ID": 68,
                "Functionality_ID": 126,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/profile/new"
          },
          {
            "FunctionalityID": 127,
            "Name": "List",
            "Action": "/list",
            "Icon": "view_list",
            "System_ID": 21,
            "FunctionalityFather_ID": 125,
            "Active": 1,
            "Priority": 2,
            "ProfileFunctionalities": [
              {
                "ProfileFunctionalityID": 1270,
                "Profile_ID": 68,
                "Functionality_ID": 127,
                "CanInsert": true,
                "CanUpdate": true,
                "CanDelete": true
              }
            ],
            "ActionFull": "/profile/list"
          }
        ],
        "ProfileFunctionalities": [
          {
            "ProfileFunctionalityID": 1268,
            "Profile_ID": 68,
            "Functionality_ID": 125,
            "CanInsert": false,
            "CanUpdate": false,
            "CanDelete": false
          }
        ],
        "ActionFull": "/profile",
        "HasFunctionalities": true,
        "model": false
      }
    ]

上面的代码对我有用,但是我认为还存在另一个代码,我想学习它:

The code above works for me but I think exist another code more sugar and I want learn it:

let all = bigArray.reduce((prev, next) => {
   return prev.concat(next.FunctionalityChildren)
}, [])

bigArray.reduce((prev, next) => all.push(next), [])

let desired1 = '/budget'
let desired2 = '/budget/allocation'

let element1 = all.find(e=>e.ActionFull === desired1) // return the object that contains ActionFull = '/budget' (can be father)
let element2 = all.find(e=>e.ActionFull === desired2) // return the object that contains ActionFull = '/budget/allocation' (can be child)

console.log(element1)
console.log(element2)

请注意,如上所述,它可以是父亲或孩子.

Pay attention, as I showed above, It can be a father or a child.

推荐答案

这是我们期望通用deepFind函数起作用的方式

Here's how we expect our generic deepFind function to work

deepFind (x => x.ActionFull === '/budget', bigArray)
// { FunctionalityID: 105, Name: 'Budget', ActionFull: '/budget' ... }

deepFind (x => x.ActionFull === '/budget/allocation', bigArray)
// { FunctionalityID: 106, Name: 'Allocation', ActionFull: '/budget/allocation' }

我将为您提供命令式样式解决方案,以期使您考虑如何构造函数调用.请注意,该程序将开始通过一组可能的解决方案进行迭代,但是一旦找到匹配项,它将停止迭代并返回结果.使用Array#reduceArray#mapArray#filter不足以完成此任务,因为它们没有我们正在寻找的短路行为

I'm going to give you the imperative style solution in hopes that this gets you thinking about how you will need to structure your function calls. Notice that this program will begin iterating thru a possible set of solutions but it stops iterating and returns a result as soon as a match is found. Using Array#reduce or Array#map or Array#filter is inadequate for this task as they do not have the short-circuiting behavior we're looking for

在浏览器中运行下面的程序,这次使用简化的数据集.遵循我们如何得出结果应该很容易

Run the program below in your browser, this time with a simplified data set. It's should be easy to follow how we arrive at the result

const data =
  [ { a: 1, b: 1 }
  , { a: 2, b: 2, c: { d: [ { e: 2 } ] } }
  , { a: 3, b: { c: { d: { e: { f: 3 } } } } }
  ]

const deepFind = (f, obj = {}) =>
{ if (Object (obj) === obj)
  { if (f (obj) === true)
      return obj

    for (const [ k, v ] of Object.entries (obj))
    { const res =
        deepFind (f, v)
      
      if (res !== undefined)
        return res
    }
  }

  return undefined
}

console.log
  ( deepFind (x => x.a === 1, data)             // { a: 1, b: 1 }
  , deepFind (x => x.e === 2, data)             // { e: 2 }
  , deepFind (x => Array.isArray(x.d), data)    // { d: [ { e: 2 } ] }
  , deepFind (x => x.f === 3, data)             // { f: 3 }
  , deepFind (x => x.e && x.e.f === 3, data)    // { e: { f: 3 } }
  , deepFind (x => x.z === 9, data)             // undefined
  )

deepFind适用于所有对象,包括数组

deepFind works for all objects, arrays included

const alpha =
  [ [ 'a', 'b', 'c' ], [ 'd', 'e', 'f' ], [ 'g', 'h', 'i' ] ]

deepFind (x => x [1] === 'h', alpha)
// [ 'g', 'h', 'i', ]

deepFind (([ _0, _1, _2 ]) => _2 === 'f', alpha)
// [ 'd', 'e', 'f' ]

deepFind表示为功能程序仅需要将迭代循环转换为带有状态参数的递归函数.因为您是自己设计递归函数的,所以可以对程序要求的短路行为进行编码.

Expressing deepFind as a functional program requires only the translation of an iterative loop to a recursive function with state parameters. Because you design the recursive function yourself, you can encode the short-circuit behavior this program requires.

下面,deepFind使用纯函数表达式编写.添加了状态参数vrest,但只有fo是要由用户指定的,就像我们上面所做的那样.如果您不希望将这些作为函数的公共接口的一部分,则可以使用内部辅助函数代替.

Below, deepFind is written using a pure functional expression. State parameters v and rest are added but only f and o are meant to be specified by the user, like we did above. If you didn't want these as part your function's public interface, an internal auxiliary function could be used instead.

const identity = x =>
  x

const None =
  Symbol ()

const deepFind = (f = identity, o = {}, [ _, v ] = [ None, None ], ...rest) =>
  Object (o) === o
    ? f (o) === true
      ? o
      : v === None
        ? deepFind (f, null, ...Object.entries (o))
        : deepFind (f, v, ...rest, ...Object.entries (o)) 
    : v === None
      ? undefined
      : deepFind (f, v, ...rest )

重新运行程序以验证输出确实相同

Re-run the program to verify that the output is indeed the same

const identity = x =>
  x

const None =
  Symbol ()

const deepFind = (f = identity, o = {}, [ _, v ] = [ None, None ], ...rest) =>
  Object (o) === o
    ? f (o) === true
      ? o
      : v === None
        ? deepFind (f, null, ...Object.entries (o))
        : deepFind (f, v, ...rest, ...Object.entries (o)) 
    : v === None
      ? undefined
      : deepFind (f, v, ...rest )

const data =
  [ { a: 1, b: 1 }
  , { a: 2, b: 2, c: { d: [ { e: 2 } ] } }
  , { a: 3, b: { c: { d: { e: { f: 3 } } } } }
  ]

console.log
  ( deepFind (x => x.a === 1, data)             // { a: 1, b: 1 }
  , deepFind (x => x.e === 2, data)             // { e: 2 }
  , deepFind (x => Array.isArray(x.d), data)    // { d: [ { e: 2 } ] }
  , deepFind (x => x.f === 3, data)             // { f: 3 }
  , deepFind (x => x.e && x.e.f === 3, data)    // { e: { f: 3 } }
  , deepFind (x => x.z === 9, data)             // undefined
  )

const alpha =
  [ [ 'a', 'b', 'c' ], [ 'd', 'e', 'f' ], [ 'g', 'h', 'i' ] ]

console.log
  ( deepFind (x => x [1] === 'h', alpha)              // [ 'g', 'h', 'i', ]
  , deepFind (([ _0, _1, _2 ]) => _2 === 'f', alpha)  // [ 'd', 'e', 'f' ]
  )

最后,这是一个deepFindAll.在此程序的变体中,我们得到的结果为 array 而不是单个答案或undefined,结果为零或更多.这演示了我在前面的示例中提到的辅助循环,以及一个漂亮的生成器用例.

Lastly, here's a deepFindAll. In this variation of the program, instead of getting a single answer or undefined, we get an array of zero or more results. This demonstrates the auxiliary loop I mentioned in the previous example and also a beautiful use case for generators.

作为练习,我建议您使用函数表达式代替辅助生成器来重写下面的deepFindAll

As an exercise, I encourage you to rewrite deepFindAll below using a functional expression in place of the auxiliary generator

const deepFindAll = (f, o = {}) =>
{ const aux =
    function* (f, o)
    { if (Object (o) === o)
      { if (f (o) === true)
          yield o
        for (const [ _, v ] of Object.entries (o))
          yield* aux (f, v)
      }
    }
  return Array.from (aux (f, o))
}

const data =
  [ { a: 1, b: 1 }
  , { a: 2, b: 2, c: { d: [ { e: 2 } ] } }
  , { a: 3, b: { c: { d: { e: { f: 3 } } } } }
  ]

console.log
  ( deepFindAll (x => x.a === 1 || x.e === 2, data)  // [ { a: 1, b: 1 }, { e: 2 } ]
  , deepFindAll (x => x.e !== undefined, data)       //[ { e: 2 }, { e: { f: 3 } } ]
  , deepFindAll (x => x.z === 9, data)               // []
  )

这篇关于使用检查属性的子数组在数组中查找对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆