什么是一个简单快速的方法来获得一个从一开始就返回最多N个元素的迭代器List?
我能想出的最简单的版本是:
#1:
import com.google.common.collect.Iterators;
// ...
public static <E> Iterator<E> lengthLimitedIterator(Iterable<E> source, int maxLen) {
return Iterators.partition(source.iterator(), maxLen).next().iterator();
}
Run Code Online (Sandbox Code Playgroud)
#2:
public static <E> Iterator<E> lengthLimitedIterator(List<E> source, int maxLen) {
return source.subList(0, Math.min(source.size(), maxLen)).iterator();
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,两个版本都创建了一个临时性List,这会显着影响性能,因为我在紧密循环中调用了这个方法数百万次
我可以使用其他任何库函数吗?
注意:我无法避免遍历列表,因为我将它传递给一个以迭代器作为参数的方法,我无法修改该类.
问题:如何生成导航,允许从多维数组中将不同的类应用于不同的子项?
在我需要多级导航之前,我就是这样做的:
Home
Pics
About
Run Code Online (Sandbox Code Playgroud)
并通过调用nav()生成:
function nav(){
$links = array(
"Home" => "home.php",
"Pics" => "pics.php",
"About" => "about.php"
);
$base = basename($_SERVER['PHP_SELF']);
foreach($nav as $k => $v){
echo buildLinks($k, $v, $base);
}
}
Run Code Online (Sandbox Code Playgroud)
这是buildLinks():
function buildLinks($name, $page, $selected){
if($selected == $page){
$theLink = "<li class=\"selected\"><a href=\"$page\">$name</a></li>\n";
} else {
$thelink = "<li><a href=\"$page\">$name</a></li>\n";
}
return $thelink;
}
Run Code Online (Sandbox Code Playgroud)
我的问题,再次:
我将如何实现以下导航(并注意到可见的子导航元素仅在该特定页面上出现时):
Home
something1
something2
Pics
About
Run Code Online (Sandbox Code Playgroud)
和...
Home
Pics
people
places
About
Run Code Online (Sandbox Code Playgroud)
我试过的
从它看来,SPL中的某些迭代器似乎很适合这个,但我不知道如何处理它.我玩过RecursiveIteratorIterator,但我不知道如何将不同的样式仅应用于子菜单项,以及如何在正确的页面上显示这些项目.
我构建了这个数组来测试,但不知道如何单独使用子菜单项:
$nav = array(
array(
"Home" …Run Code Online (Sandbox Code Playgroud) 我正在使用第三方库来返回原始迭代器,例如
Iterator<?> children = element.getChildElements();
Run Code Online (Sandbox Code Playgroud)
我知道实际的类型,但我不一定相信第三方lib将来会坚持使用它.有两种(我可以想到)有些冒险的方法来遍历这个:
@SuppressWarnings("unchecked")
Iterator<ActualObject> currentChildren = (Iterator<ActualObject>)currentElement.getChildElements();
Run Code Online (Sandbox Code Playgroud)
要么
Iterator<?> children = element.getChildElements();
while (null != children && children.hasNext()) {
ActualObject child = (ActualObject)children.next(); //Possible ClassCastException @ runtime
...
}
Run Code Online (Sandbox Code Playgroud)
我可以想出来遍历这种迭代器的唯一"安全"方法如下:
Iterator<?> children = element.getChildElements();
while (null != children && children.hasNext()) {
Object obj = children.next();
ActualObject child = null;
if (obj instanceof ActualObject)
child = (ActualObject)obj;
...
}
Run Code Online (Sandbox Code Playgroud)
这似乎过于冗长.是否有更好,但同样"安全"的方式来遍历原始迭代器?
编辑:我意识到我可以在else块中捕获/记录异常,我正在寻找(希望)Java语言等同于ColinD在下面提到的内容.
我非常喜欢for(T e : iterable)Java中的for-each-loop构造(),Iterable<T>因为它在很多情况下非常容易阅读和编写代码.
我想知道是否有任何方法可以从这样的循环访问底层迭代器.如果我想remove()从迭代器中使用它,这可以是必需的.
我有许多意识中继器,我需要遍历所有项目.我目前有:
For Each item In rpt1.Items
...do some stuff
Next
For Each item In rpt2.Items
...exact same code
Next
Run Code Online (Sandbox Code Playgroud)
有没有一种简单的方法可以将其减少为单个For Each ... Next循环?
编辑:"做一些事情"涉及到许多本地变量,这就是为什么我不能只将项目传递给函数 - 调用必须包含大约8个ByRef参数.
我很困惑python如何迭代这本词典.从python的文档中,itervalues返回字典值的迭代器.
dict = {"hello" : "wonderful", "today is" : "sunny", "more text" : "is always good"}
for x in dict.itervalues():
x = x[2:]
print dict
Run Code Online (Sandbox Code Playgroud)
这会打印出原始字典不变.这是为什么?如果我说位置x的值是"blabla",为什么不设置?
根据大多数C++引用,例如cplusplus.com,前向迭代器不需要是可赋值的(我的意思是,引用左值).但是,对于需要写入值的几个STL算法std::fill(例如std::generate等),规范使用了前向迭代器:
template <class ForwardIterator, class T>
void fill (ForwardIterator first, ForwardIterator last, const T& val);
Run Code Online (Sandbox Code Playgroud)
而等效行为需要左值取消引用:
template <class ForwardIterator, class T>
void fill (ForwardIterator first, ForwardIterator last, const T& val)
{
while (first != last) {
*first = val;
++first;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,它实际上是使用一个可变的前向迭代器和一次传递.
现在的问题是:
(1)为什么不明确这些情况下使用的前向迭代器是否可变?
(2)更新:我发现以下问题是愚蠢的:我暂时忘记了输出迭代器不需要支持相等比较.无论如何,上述问题仍然存在.
为什么使用前向迭代器,而不是输出迭代器std::fill,std::generate等等,而他们实际上并不需要多遍?(std::copy例如,只需要输出迭代器.基本原理是什么?)
cppreference显示以下签名std::cbegin:
template< class C >
constexpr auto cbegin( const C& c ) -> decltype(std::begin(c));
Run Code Online (Sandbox Code Playgroud)
不应该返回类似的东西C::const_iterator吗?
我尝试创建接收特定时间类型的模板参数的迭代式,说std::seconds,std::hours等等,我希望它获得作为参数2点的值表示time_points指定的持续时间,并能够使用这样的构建在基于循环的范围内,time_point通过以该持续时间或可能具有指定持续时间为单位增加电流,如下所示:
DateRange<std::seconds> dr(now() , 50);
for(auto d : dr){
// do something at unit time
}
Run Code Online (Sandbox Code Playgroud)
我试图用这种方式实现它
using namespace std::chrono;
template<typename Duration , typename Clock_t = high_resolution_clock,
typename Time_type = time_point<Clock_t, typename Duration> , typename
Time_pointer = Time_type* >
class DateRange {
using Time_type_t = typename Time_type::duration;
public:
DateRange(Time_type_t start, Time_type_t end) :
m_begin(start),
m_end(end)
{
}
DateRange(Time_type_t end):
m_begin(Clock_t::now())
{
}
Time_pointer begin(){
return &m_begin;
}
Time_pointer end() {
return &m_end; …Run Code Online (Sandbox Code Playgroud) 我有一个可以简化为基本的并行代码:
#include <algorithm>
#include <vector>
struct TKeyObjPtr;
class TObj
{
public:
virtual void Calculate(TKeyObjPtr const &) = 0;
};
struct TKeyObjPtr
{
int Key;
TObj *ObjPtr;
};
void Calculate(std::vector<TKeyObjPtr> const &KeyObjPtrVec)
{
#pragma omp parallel for
for (auto It1= KeyObjPtrVec.begin(); It1!=KeyObjPtrVec.end(); ++It1)
for (auto It2= It1+1; It2!=KeyObjPtrVec.end() && It2->Key==It1->Key; ++It2)
It1->ObjPtr->Calculate(*It2);
}
Run Code Online (Sandbox Code Playgroud)
我想通过使用c ++ 17并行算法来实现代码的现代化.不幸的是,我在重写这么简单的代码时遇到了麻烦.
一个选项将使用boost::counting_iterator:
void Calculate(std::vector<TKeyObjPtr> const &KeyObjPtrVec)
{
std::for_each(std::execution::par_unseq,
boost::counting_iterator<std::size_t>(0u),
boost::counting_iterator<std::size_t>(KeyObjPtrVec.size()),
[&KeyObjPtrVec](auto i)
{
for (auto j= i+1; j<KeyObjPtrVec.size() && KeyObjPtrVec[j].Key==KeyObjPtrVec[i].Key; ++j)
KeyObjPtrVec[i].ObjPtr->Calculate(KeyObjPtrVec[j]); …Run Code Online (Sandbox Code Playgroud)