我创建了某种功能的“深度”嵌套数组过滤功能。此功能显示汽车,并为其分配了颜色“红色”。但是,“通过”过滤器的汽车是仅分配了1种颜色的汽车。
如何确保标准中检查了阵列中的阵列?我是否需要在循环内创建循环?理想的结果是,如果将标准设置为“红色”,由于这些汽车也具有此颜色,因此还将显示BMW和SUZUKI。
由于我自己找不到任何非常有用的东西,因此对获得任何帮助,建议或与其他帖子的其他链接以取得理想的结果表示衷心的感谢。该帖子最有用的就是这一篇-Filtering an array with a deeply nested array in JS
在下面,我附上了我当前代码的代码片段。
class TrayTooltip
{
public static List<string> ScanToolbarButtons()
{
List<string> tooltips = new List<string>();
var handle = GetSystemTrayHandle();
if (handle == IntPtr.Zero)
{
return null;
}
var count = SendMessage(handle, TB_BUTTONCOUNT, IntPtr.Zero, IntPtr.Zero).ToInt32();
if (count == 0)
{
return null;
}
GetWindowThreadProcessId(handle, out var pid);
var hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if (hProcess == IntPtr.Zero)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
var size = (IntPtr)Marshal.SizeOf<TBBUTTONINFOW>();
var buffer = VirtualAllocEx(hProcess, IntPtr.Zero, size, MEM_COMMIT, PAGE_READWRITE);
if (buffer == IntPtr.Zero)
{
CloseHandle(hProcess);
throw new Win32Exception(Marshal.GetLastWin32Error());
}
for (int i = 0; i < count; i++)
{
var btn = new TBBUTTONINFOW();
btn.cbSize = size.ToInt32();
btn.dwMask = TBIF_BYINDEX | TBIF_COMMAND;
if (WriteProcessMemory(hProcess, buffer, ref btn, size, out var written))
{
// we want the identifier
var res = SendMessage(handle, TB_GETBUTTONINFOW, (IntPtr)i, buffer);
if (res.ToInt32() >= 0)
{
if (ReadProcessMemory(hProcess, buffer, ref btn, size, out var read))
{
// now get display text using the identifier
// first pass we ask for size
var textSize = SendMessage(handle, TB_GETBUTTONTEXTW, (IntPtr)btn.idCommand, IntPtr.Zero);
if (textSize.ToInt32() != -1)
{
// we need to allocate for the terminating zero and unicode
var utextSize = (IntPtr)((1 + textSize.ToInt32()) * 2);
var textBuffer = VirtualAllocEx(hProcess, IntPtr.Zero, utextSize, MEM_COMMIT, PAGE_READWRITE);
if (textBuffer != IntPtr.Zero)
{
res = SendMessage(handle, TB_GETBUTTONTEXTW, (IntPtr)btn.idCommand, textBuffer);
if (res == textSize)
{
var localBuffer = Marshal.AllocHGlobal(utextSize.ToInt32());
if (ReadProcessMemory(hProcess, textBuffer, localBuffer, utextSize, out read))
{
var text = Marshal.PtrToStringUni(localBuffer);
tooltips.Add(text);
}
Marshal.FreeHGlobal(localBuffer);
}
VirtualFreeEx(hProcess, textBuffer, IntPtr.Zero, MEM_RELEASE);
}
}
}
}
}
}
VirtualFreeEx(hProcess, buffer, IntPtr.Zero, MEM_RELEASE);
CloseHandle(hProcess);
return tooltips;
}
private static IntPtr GetSystemTrayHandle()
{
var hwnd = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "Shell_TrayWnd", null);
hwnd = FindWindowEx(hwnd, IntPtr.Zero, "TrayNotifyWnd", null);
hwnd = FindWindowEx(hwnd, IntPtr.Zero, "SysPager", null);
return FindWindowEx(hwnd, IntPtr.Zero, "ToolbarWindow32", null);
}
[DllImport("kernel32", SetLastError = true)]
private static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32", SetLastError = true)]
private static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32", SetLastError = true)]
private static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, ref TBBUTTONINFOW lpBuffer, IntPtr nSize, out IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32", SetLastError = true)]
private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, ref TBBUTTONINFOW lpBuffer, IntPtr nSize, out IntPtr lpNumberOfBytesRead);
[DllImport("kernel32", SetLastError = true)]
private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, IntPtr nSize, out IntPtr lpNumberOfBytesRead);
[DllImport("user32", SetLastError = true)]
private static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
[DllImport("kernel32", SetLastError = true)]
private static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, IntPtr dwSize, int flAllocationType, int flProtect);
[DllImport("kernel32", SetLastError = true)]
private static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, IntPtr dwSize, int dwFreeType);
[DllImport("user32")]
private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr hWndParent, IntPtr hWndChildAfter, string lpClassName, string lpWindowName);
private const int TBIF_BYINDEX = unchecked((int)0x80000000); // this specifies that the wparam in Get/SetButtonInfo is an index, not id
private const int TBIF_COMMAND = 0x20;
private const int MEM_COMMIT = 0x1000;
private const int MEM_RELEASE = 0x8000;
private const int PAGE_READWRITE = 0x4;
private const int TB_GETBUTTONINFOW = 1087;
private const int TB_GETBUTTONTEXTW = 1099;
private const int TB_BUTTONCOUNT = 1048;
private static bool IsWindowsVistaOrAbove() => Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major >= 6;
private static int PROCESS_ALL_ACCESS => IsWindowsVistaOrAbove() ? 0x001FFFFF : 0x001F0FFF;
[StructLayout(LayoutKind.Sequential)]
private struct TBBUTTONINFOW
{
public int cbSize;
public int dwMask;
public int idCommand;
public int iImage;
public byte fsState;
public byte fsStyle;
public short cx;
public IntPtr lParam;
public IntPtr pszText;
public int cchText;
}
}
const myCars = [
{ name: "BMW",colour: ["White","Red","Black"] },
{ name: "AUDI",colour: ["Yellow","Silver"] },
{ name: "VW",colour: ["Purple","Gold"] },
{ name: "NISSAN",colour: ["White","Black"] },
{ name: "SUZUKI",colour: ["Red"] },
];
for (x in myCars) {
var keys = Object.keys(myCars[x])
var carSpec = myCars.filter(function(fltr) {
return (fltr.colour == "Red");
});
document.getElementById("show1").innerHTML += carSpec[x].name + " " + "has these colours - " + carSpec[x].colour + "<hr />";
}
答案 0 :(得分:4)
您需要对filter
数组进行includes
测试,colour
:
const myCars = [
{ name: "BMW",colour: ["White","Red","Black"] },
{ name: "AUDI",colour: ["Yellow","Silver"] },
{ name: "VW",colour: ["Purple","Gold"] },
{ name: "NISSAN",colour: ["White","Black"] },
{ name: "SUZUKI",colour: ["Red"] },
];
const show1 = document.getElementById("show1");
myCars
.filter(({ colour }) => colour.includes('Red'))
.forEach(({ name, colour }) => {
show1.innerHTML += name + " " + "has these colours - " + colour + "<hr />";
});
<p>Car List.</p>
<p id="show"></p>
<p id="show1"></p>
答案 1 :(得分:1)
您可以使用reduce
获取一系列可用红色显示的汽车,然后使用forEach
对其进行循环并显示文本。
join
将通过定界符连接数组的所有内容
const myCars = [{
name: "BMW",
colour: ["White", "Red", "Black"]
},
{
name: "AUDI",
colour: ["Yellow", "Silver"]
},
{
name: "VW",
colour: ["Purple", "Gold"]
},
{
name: "NISSAN",
colour: ["White", "Black"]
},
{
name: "SUZUKI",
colour: ["Red"]
},
];
let hasRed = myCars.reduce(function(acc, curr) {
if (curr.colour.indexOf('Red') !== -1) {
acc.push(curr)
}
return acc;
}, []).forEach((item) => {
document.getElementById("show1").innerHTML += item.name + " " + "has these colours - " + item.colour.join(',') + "<hr />";
})
<p>Car List.</p>
<p id="show"></p>
<p id="show1"></p>