中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » 如何能够实现延迟扩展下的map lookup?
作者:
标题: 如何能够实现延迟扩展下的map lookup? 上一主题 | 下一主题
leson
初级用户





积分 35
发帖 15
注册 2007-12-9
状态 离线
『楼 主』:  如何能够实现延迟扩展下的map lookup?

在一般情形下,可以walkaround实现map的键值查找。
SET key=fri

set map=mon-Monday;tue-Tuesday;wed-Wednesday;thu-Thursday;fri-Friday;sat-Saturday;sun-Sunday
call set value=%%map:*%key%-=%%
set value=%value:;=&rem.%

echo.%value%
但是如何在for循环中实现类似的查找呢?例如当前给出的不是一个键,而是一组键,然后要将它们所对应的值串起来后用。
set "keys=fri mon"
set map=mon-Monday;tue-Tuesday;wed-Wednesday;thu-Thursday;fri-Friday;sat-Saturday;sun-Sunday
set "list="
for %%I in ("%keys: =" "") do (
    set "key=%%~I"
    call set value=%%map:*!key!-=%%
    set value=!value:;=&rem.%
    set "list=!list! !value!"
)

echo.%list%
如上尝试,结果不正确,应该是由于变量延迟扩展所引起的,导致每个迭代下的&rem.都不能立刻摔倒,最后list只能获取到第一个匹配值。

希望大家多多指点,谢谢。

2008-9-22 20:21
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
HAT
版主





积分 9023
发帖 5017
注册 2007-5-31
状态 离线
『第 2 楼』:  

这个是由批处理在进行预处理时符号的优先级决定的:
%%大于&大于!!

在未开启变量延迟扩展的时候,先进行变量替换,后处理&符号,所以你的这个方法行得通;开启变量延迟扩展以后,先处理&符号,后进行变量替换,所以你的这个方法就行不通了。



2008-9-22 22:40
查看资料  发短消息 网志   编辑帖子  回复  引用回复
leson
初级用户





积分 35
发帖 15
注册 2007-12-9
状态 离线
『第 3 楼』:  

这只是我看到过的一种思路,
请问一般大家都用什么方法实现map的lookup,
直接用set "days.mon=Monday"这种方式我是知道的,
还有其他方法吗?
谢谢。

2008-9-23 06:58
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
lxmxn
版主




积分 11386
发帖 4938
注册 2006-7-23
状态 离线
『第 4 楼』:  


@echo off & setlocal EnableDelayedExpansion

set "keys=fri mon"
set map=mon-Monday;tue-Tuesday;wed-Wednesday;thu-Thursday;fri-Friday;sat-Saturday;sun-Sunday
set "list="
for %%i in (%keys%) do (
    for %%k in (%map%) do (
        set str=%%k
        if /i "!str:~,3!"=="%%i" set list=!list! !str:~4!
    )
)

echo.%list%


2008-9-23 14:05
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
leson
初级用户





积分 35
发帖 15
注册 2007-12-9
状态 离线
『第 5 楼』:  

楼上的方法挺别致的,
以前我倒不知道;分隔的序列放在for ... in里面也可以遍历的,
而且map lookup,复杂度n^2倒也是可以接受的,
非常感谢。

按照我原来的思路,今天我还是实验出了如何walkaround那个!!、%%、&优先级问题。
方法是通过for转一下,用echo弄掉后面的&rem.,然后再执行直接值set,
想来自我感觉也不错,特分享下。
@echo off
setlocal ENABLEEXTENSIONS
setlocal ENABLEDELAYEDEXPANSION

set "keys=fri mon"
set "map=mon-Monday;tue-Tuesday;wed-Wednesday;thu-Thursday;fri-Friday;sat-Saturday;sun-Sunday"
set "list="
for %%I in ("%keys: =" "%") do (
    set "key=%%~I"
    call set "value=%%map:*!key!-=%%"
    set "value=!value:;=&rem.!"
    for /F "delims=" %%A in ('"echo.set value=!value!"') do %%A
    set "list=!list! !value!"
)

echo.%list%


2008-9-23 20:13
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
leson
初级用户





积分 35
发帖 15
注册 2007-12-9
状态 离线
『第 6 楼』:  

顺便说下,我当初遭遇问题的原始需求是,动态生成带序号的目录列表,然后交互时,用户可以输入序号列表,来选择相应的待处理目录。
在始终无法使用&rem.替换方法来实现序号列表和目录列表的映射时,
当初我用到的是一种相对简单直观一点的方法,就是在创建dirs menu的for循环中,
每个迭代中set一个新变量出来,
set /A index=0
for %%I in ("%dirs::=" "%") do (
    set "dir=%%~I"
    set /A index=!index!+1
    echo.    !index! !dir!
    set "dirs.!index!=!dir!"
)
映射时就相对简单些了,
set "list="
for %%I in (%choices%) do (
    set /A "choice=%%~I"
    if !choice! GEQ 1 (
        if !choice! LEQ %index% (
            call set "list=!list!:%%dirs.!choice!%%"
        )
    )
)
if "%list%"=="" (
    echo.None valid choices, try again.
    goto :selecting
)
set "dirs=%list:~1%"


2008-9-23 20:22
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: