我需要通过匹配关键字来过滤嵌套数组。它必须返回与父级或其子项之一的name属性匹配的所有对象,并且还要过滤其子项。
示例:
[
{
"name": "abc",
"children": [
{ "name": "abcd" },
{ "name": "efg" }
]
},
{
"name": "hjk",
"children": [
{ "name": "lmn" },
{ "name": "opq" }
]
},
{
"name": "xyz",
"children": [
{ "name": "lmn" },
{ "name": "abcdef" }
]
}
]
如果文本输入为“ ab”,则它必须返回:
[
{
"name": "abc",
"children": [
{ "name": "abcd" }
]
},
{
"name": "xyz",
"children": [
{ "name": "abcdef" }
]
}
]
(它与父代OR或至少一个子代匹配,但返回但有父代和子代)
现在,我只能像这样过滤父母:
filteredArray = _.filter(array, (parent) => {
return _.includes(_.toLower(parent.name), _.toLower(filterText));
});
我该如何修改它以便也过滤孩子?
编辑: 父级可以有空或无子级数组。
答案 0 :(得分:1)
恕我直言,您可以使用Array#reduce()
方法执行以下操作:
arr = [{"name":"abc","children":[{"name":"abcd"},{"name":"efg"}]},{"name":"hjk","children":[{"name":"lmn"},{"name":"opq"}]},{"name":"xyz","children":[{"name":"lmn"},{"name":"abcdef"}]}, {"name": "xyz"}]
var input = "ab"
filteredArr = arr.reduce((accum, ele) => {
var obj = {};
ele['children'] && ele['children'].forEach(e => {
if (e['name'].includes(ele['name']) || e['name'].includes(input)) {
obj['name'] = ele['name'];
obj['children'] ? (obj['children'].push(e)) : (obj['children'] = [], obj['children'].push(e))
}
})
if (Object.keys(obj).length > 0) accum.push(obj);
return accum;
}, [])
console.log(filteredArr);
答案 1 :(得分:1)
为每个元素检查名称并过滤其子元素,如果其中一个为真,则将具有已过滤子元素的元素推入新数组
const data = [{"name": "abc", "children": [{ "name": "abcd" }, { "name": "efg" } ] }, {"name": "hjk","children": [{ "name": "lmn"}, { "name": "opq" } ]}, { "name": "xyz","children": [{ "name": "lmn"
},{"name": "abcdef" } ] }, {"name": "abc"}, {"name": "abc", children: []}];
const res = data.reduce((acc, a) => {
const ch = a.children && a.children.filter(b => b.name.includes('ab'));
if(ch && ch.length) acc.push({...a, children: ch});
else if(a.name.includes('ab')) acc.push({ name: a.name });
return acc;
}, []);
console.log(res);
答案 2 :(得分:1)
lodash
中没有真正的需求。 #nodash!只是现代香草JS:
const regExp = new RegExp(filterText, 'i');
const result = array.reduce((acc, { name, children = [] }) => {
const next = children.filter(child => child.name.match(regExp));
if (name.match(regExp) || next.length > 0) {
acc.push({ name, children: next });
}
return acc;
}, []);
如果找不到子字符串, name.match(regExp)
将返回null
。
children = []
处理parent
没有孩子的情况。
另外,请注意,使用RegExp检查子字符串应该比执行多次转换和查找(例如toLower
,includes
)要快得多。
这是工作中的repl with your example。
答案 3 :(得分:0)
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Enabling debug mode 0
I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@2ebe9688 time:2777009
D/ROOT: Root access requested
D/Camera2VideoFragment: tryAcquire
I/CameraManagerGlobal: getCameraService: Reconnecting to camera service
E/Camera2VideoFragment: Couldn't find any suitable preview size
D/Camera2VideoFragment: openCamera: Intialising New MediaRecorder.
D/Camera2VideoFragment: openCamera: Manager.openCamera called here: 1532504895664
I/CameraManager: Using legacy camera HAL.
D/Camera2VideoFragment: onOpened: This is called: 1532504896165
I/CameraDeviceState: Legacy camera service transitioning to state CONFIGURING
I/RequestThread-0: Configure outputs: 1 surfaces configured.
D/Camera: app passed NULL surface
I/CameraDeviceState: Legacy camera service transitioning to state IDLE
I/RequestQueue: Repeating capture request set.
W/LegacyRequestMapper: convertRequestMetadata - control.awbRegions setting is not supported, ignoring value
W/LegacyRequestMapper: convertRequestToMetadata - Ignoring android.lens.focusDistance false, only 0.0f is supported
I/CameraDeviceState: Legacy camera service transitioning to state CAPTURING
E/BufferQueueProducer: [unnamed-8823-1] dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=6 undequeued=0)
E/BufferQueueProducer: [unnamed-8823-1] dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=5 undequeued=1)
D/Camera2VideoFragment: onClick: NUM_OF_RESTARTS click: 0
I/RequestQueue: Repeating capture request cancelled.
I/CameraDeviceState: Legacy camera service transitioning to state CONFIGURING
I/RequestThread-0: Configure outputs: 2 surfaces configured.
D/Camera: app passed NULL surface
I/CameraDeviceState: Legacy camera service transitioning to state IDLE
I/RequestQueue: Repeating capture request set.
W/LegacyRequestMapper: convertRequestMetadata - control.awbRegions setting is not supported, ignoring value
W/LegacyRequestMapper: convertRequestToMetadata - Ignoring android.lens.focusDistance false, only 0.0f is supported
V/RenderScript: 0xb7cfa0a0 Launching thread(s), CPUs 4
E/BufferQueueProducer: [unnamed-8823-2] dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=6 undequeued=0)
I/CameraDeviceState: Legacy camera service transitioning to state CAPTURING
E/BufferQueueProducer: [unnamed-8823-2] dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=5 undequeued=1)
D/Camera2VideoFragment: MediaRecorder onInfo: 801 extra: 0
D/Camera2VideoFragment: run: calling onVideoInfo here: 1532504954189
onVideoInfo: what: 801 extra: 0
onVideoInfo: Thread Name: main
onVideoInfo: MAX FILE SIZE APPROACHING
onVideoInfo: Calling stopRecordingVideo: 1532504954189
D/Camera2VideoFragment: restartRecordingVideo: Stoping Video From restart: 1532504954193
stopRecordingVideo: Stop Video Recording
stopRecordingVideo: About to call mMediaRecorder.stop()
W/Adreno-EGLSUB: <DequeueBuffer:736>: dequeue native buffer fail: No such device, buffer=0x0, handle=0x0
W/Adreno-EGL: <qeglDrvAPI_eglSwapBuffers:3709>: EGL_BAD_SURFACE
E/CameraDeviceGLThread-0: Received exception on GL render thread:
java.lang.IllegalStateException: swapBuffers: EGL error: 0x300d
at android.hardware.camera2.legacy.SurfaceTextureRenderer.checkEglError(SurfaceTextureRenderer.java:530)
at android.hardware.camera2.legacy.SurfaceTextureRenderer.swapBuffers(SurfaceTextureRenderer.java:523)
at android.hardware.camera2.legacy.SurfaceTextureRenderer.drawIntoSurfaces(SurfaceTextureRenderer.java:729)
at android.hardware.camera2.legacy.GLThreadManager$1.handleMessage(GLThreadManager.java:105)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:135)
at android.os.HandlerThread.run(HandlerThread.java:61)
I/CameraDeviceState: Legacy camera service transitioning to state ERROR
D/Camera2VideoFragment: stopRecordingVideo: Done mMediaRecorder.stop()
stopRecordingVideo: Reset mMediaRecorder
stopRecordingVideo: Release mMediaRecorder
D/Camera2VideoFragment: stopRecordingVideo: Closing Camera: 1532504954421
closeCamera: mCameraDevice.close() called here.
E/RequestThread-0: Timed out while waiting for request to complete.
W/CaptureCollector: Preview buffers dropped for request: 1
E/CameraDeviceState: Cannot receive result while in state: 0
Cannot receive result while in state: 0
E/CameraDeviceState: Cannot receive result while in state: 0
W/MessageQueue: Handler (android.graphics.SurfaceTexture$1) {63c0706} sending message to a Handler on a dead thread
java.lang.IllegalStateException: Handler (android.graphics.SurfaceTexture$1) {63c0706} sending message to a Handler on a dead thread
at android.os.MessageQueue.enqueueMessage(MessageQueue.java:325)
at android.os.Handler.enqueueMessage(Handler.java:631)
at android.os.Handler.sendMessageAtTime(Handler.java:600)
at android.os.Handler.sendMessageDelayed(Handler.java:570)
at android.os.Handler.sendEmptyMessageDelayed(Handler.java:534)
at android.os.Handler.sendEmptyMessage(Handler.java:519)
at android.graphics.SurfaceTexture.postEventFromNative(SurfaceTexture.java:368)
E/BufferQueueProducer: [unnamed-8823-2] cancelBuffer: BufferQueue has been abandoned
E/BufferQueueProducer: [unnamed-8823-2] cancelBuffer: BufferQueue has been abandoned
E/BufferQueueProducer: [unnamed-8823-2] cancelBuffer: BufferQueue has been abandoned
E/BufferQueueProducer: [unnamed-8823-2] cancelBuffer: BufferQueue has been abandoned
E/BufferQueueProducer: [unnamed-8823-2] cancelBuffer: BufferQueue has been abandoned
D/Camera2VideoFragment: stopRecordingVideo: Opening Camera: 1532504958414
D/Camera2VideoFragment: tryAcquire
E/Camera2VideoFragment: Couldn't find any suitable preview size
D/Camera2VideoFragment: openCamera: Intialising New MediaRecorder.
openCamera: Manager.openCamera called here: 1532504958422
I/CameraManager: Using legacy camera HAL.
D/Camera2VideoFragment: onVideoInfo: came back here after restarting video recording: 1532504958920
run: returned here after onVideoInfo: 1532504958920
D/Camera2VideoFragment: onError: This is called with error: 1 at: 1532504958924
onError: cameraDevice.close() is called here: 1532504958924
D/Camera2VideoFragment: onClosed: Camera Closed: 1532504958954
D/Camera2VideoFragment: onOpened: This is called: 1532504958991
I/CameraDeviceState: Legacy camera service transitioning to state CONFIGURING
I/RequestThread-0: Configure outputs: 2 surfaces configured.
D/Camera: app passed NULL surface
I/CameraDeviceState: Legacy camera service transitioning to state IDLE
D/Camera2VideoFragment: onPause: In onPause
I/RequestQueue: Repeating capture request set.
W/LegacyRequestMapper: convertRequestMetadata - control.awbRegions setting is not supported, ignoring value
convertRequestToMetadata - Ignoring android.lens.focusDistance false, only 0.0f is supported
W/IInputConnectionWrapper: showStatusIcon on inactive InputConnection
E/BufferQueueProducer: [unnamed-8823-3] dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=6 undequeued=0)
I/CameraDeviceState: Legacy camera service transitioning to state CAPTURING
E/BufferQueueProducer: [unnamed-8823-0] dequeueBuffer: BufferQueue has been abandoned
W/Adreno-EGLSUB: <DequeueBuffer:736>: dequeue native buffer fail: No such device, buffer=0x0, handle=0x0
W/Adreno-EGL: <qeglDrvAPI_eglSwapBuffers:3709>: EGL_BAD_SURFACE
E/CameraDeviceGLThread-0: Received exception on GL render thread:
java.lang.IllegalStateException: swapBuffers: EGL error: 0x300d
at android.hardware.camera2.legacy.SurfaceTextureRenderer.checkEglError(SurfaceTextureRenderer.java:530)
at android.hardware.camera2.legacy.SurfaceTextureRenderer.swapBuffers(SurfaceTextureRenderer.java:523)
at android.hardware.camera2.legacy.SurfaceTextureRenderer.drawIntoSurfaces(SurfaceTextureRenderer.java:729)
at android.hardware.camera2.legacy.GLThreadManager$1.handleMessage(GLThreadManager.java:105)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:135)
at android.os.HandlerThread.run(HandlerThread.java:61)
I/CameraDeviceState: Legacy camera service transitioning to state ERROR
D/Camera2VideoFragment: onError: This is called with error: 1 at: 1532504959666
D/Camera2VideoFragment: onError: cameraDevice.close() is called here: 1532504959667
E/BufferQueueProducer: [unnamed-8823-3] dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=5 undequeued=1)
E/RequestThread-0: Timed out while waiting for request to complete.
W/CaptureCollector: Preview buffers dropped for request: 0
E/CameraDeviceState: Cannot receive result while in state: 0
Cannot receive result while in state: 0
E/CameraDeviceState: Cannot receive result while in state: 0
E/BufferQueueProducer: [unnamed-8823-3] queueBuffer: BufferQueue has been abandoned
E/BufferQueueProducer: [unnamed-8823-3] dequeueBuffer: BufferQueue has been abandoned
E/BufferQueueProducer: [unnamed-8823-3] cancelBuffer: BufferQueue has been abandoned
E/BufferQueueProducer: [unnamed-8823-3] cancelBuffer: BufferQueue has been abandoned
E/BufferQueueProducer: [unnamed-8823-3] cancelBuffer: BufferQueue has been abandoned
E/BufferQueueProducer: [unnamed-8823-3] cancelBuffer: BufferQueue has been abandoned
E/BufferQueueProducer: [unnamed-8823-3] cancelBuffer: BufferQueue has been abandoned
D/Camera2VideoFragment: onClosed: Camera Closed: 1532504963772
W/CameraCaptureSession: Session 1: The camera device was already closed:
java.lang.IllegalStateException: CameraDevice was already closed
at android.hardware.camera2.impl.CameraDeviceImpl.checkIfCameraClosedOrInError(CameraDeviceImpl.java:1482)
at android.hardware.camera2.impl.CameraDeviceImpl.stopRepeating(CameraDeviceImpl.java:677)
at android.hardware.camera2.impl.CameraCaptureSessionImpl.close(CameraCaptureSessionImpl.java:328)
at android.hardware.camera2.impl.CameraCaptureSessionImpl.finalize(CameraCaptureSessionImpl.java:561)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:191)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:174)
at java.lang.Thread.run(Thread.java:818)