Php 基于现有值在数组中创建新元素

Php 基于现有值在数组中创建新元素,php,arrays,Php,Arrays,我有以下数组,其中包含一组句点: Array ( Array ( [period_start] => 1 [period_end] => 12 ) Array ( [period_start] => 4 [period_end] => 8 ) ) 我想分割与其他时段重叠的时段。例如,由于第二个周期与第一个周期重叠,因此应将第一个周期拆分为两个周期,使其看起

我有以下数组,其中包含一组句点:

Array
(
    Array
    (
        [period_start] => 1
        [period_end] => 12
    )

    Array
    (
        [period_start] => 4
        [period_end] => 8
    )

)
我想分割与其他时段重叠的时段。例如,由于第二个周期与第一个周期重叠,因此应将第一个周期拆分为两个周期,使其看起来像这样:

Array
(
    Array
    (
        [period_start] => 1
        [period_end] => 3
    )

    Array
    (
        [period_start] => 4
        [period_end] => 8
    )

    Array
    (
        [period_start] => 9
        [period_end] => 12
    )

)
因此,在另一个期间的范围内,没有两个期间包含起始值和结束值。但我不知道如何以有效的方式实现这一目标。任何帮助都将不胜感激

编辑:对于这些评论,这篇文章更多的是一种对橡皮鸭的恳求,而不是为了让别人为我工作。我有一个解决我问题的办法(振作起来):

//按句点对集合进行排序\u按升序开始。
函数排序类型(&$collection){
usort($collection,function($value1,$value2){
如果(!array_key_存在('period_start',$value1)| |!array_key_存在('period_start',$value2)){
返回0;
}
如果($value1['period\u start']=$value2['period\u start'])){
返回0;
}
返回$value1['period\u start']<$value2['period\u start']?-1:1;
});
}
$periods=array();
$products=数组(
排列(
“周期开始”=>4,
“周期结束”=>8
),
排列(
“周期开始”=>1,
“周期结束”=>12
)
);
SortTyperiod($产品);
foreach($products as$product){
//使用一个键将它们存储在$periods中,这样,如果在未来的迭代中出现相同的周期,它就不会被计数。键不是必需的。
如果(数组密钥存在('period\u start',$product)&&!为null($product['period\u start'])){
如果(!array_key_)存在($product['period_start'].-'.$product['period_end'],$periods)){
$productStart=$product['period_start'];
$productEnd=$product['period_end'];
//检查已插入的每个期间
foreach($periods as&$period){
$periodStart=$period['period_start'];
$periodEnd=$period['period_end'];
如果产品的开始与期间的结束重叠
如果($productStart$periodEnd
);
//产品周期不完全在周期内(例如周期为1-6,产品为4-8)
}否则{
//添加从产品开始到期间结束的新期间(例如,按照上述示例,期间变为1-3,插入4-6)
$periods[$productStart.'-'.$periodEnd]=数组(
“period_start”=>$productStart,
“period\u end”=>$periodEnd
);
//将产品的开始设置为周期的结束+1(例如7)
$productStart=$periodEnd+1;
}
}
}
//添加周期(在上面的示例迭代之后,产品开始=7,结束=8)
$periods[$productStart.'-'.$productEnd]=数组(
“period_start”=>$productStart,
“期间结束”=>$productEnd
);
}
}
//经过一次迭代,我们得到了1-3、4-6和7-8
}
sortByPeriod($periods);
$periods=数组_值($periods);
打印(期间);
它工作并产生如上所示的预期输出。然而,正如你所看到的,它组织得不是很好,我觉得似乎有更好的方法来处理这个问题


谢谢。

我意识到我在用一种有点奇怪的方式来处理这件事。我的想法是,如果我有一个周期范围(比如说
1-8
)和另一个(
4-12
),它应该将这些范围分开,并保留
1-3、4-8、9-12
。虽然输出确实是我想要的输出,但通过拆分它并添加新的周期来补偿中间缺失的范围来实现它太复杂了。我是这样想的(我让它这样工作):

我有三块面包,每一块大小不同。我需要把它们全部分开,这样我就有了几片面包,足够大的面包的份量。好吧,让我们从这块面包中拿出一块,从那块面包中取出,放在一起。< /P> 一切都一团糟。实际上,最好的方法是用最大的面包,在其他面包适合的地方切,所以我不用三个面包,而是用一个

我将理论付诸实践(使用JavaScript。我可以将其移植到PHP)。首先,我需要一种方法来区分每个时段,这样,如果我的初始时段是沿着
1-3、1-12和4-8
,它将
1-3
4-8
计算为两个独立的时段。幸运的是,我所有的商品都是正常价格和折扣价格的产品。折扣价格在折扣期内生效

接下来,我需要确定最大的周期,并注意它的开始和结束:

var range = {};

this.products.forEach(product => {
    if (!range.start) {
        range.start = product.start;
    }

    if (!range.end) {
        range.end = product.end;
    }

    if (product.start < range.start) {
        range.start = product.start
    }

    if (product.end > range.end) {
        range.end = product.end;
    }
});
var range={};
this.products.forEach(product=>{
如果(!range.start){
range.start=product.start;
}
如果(!range.end){
range.end=product.end;
}
if(product.startrange.end){
range.end=product.end;
}
});
现在,对于每个产品,我在每次迭代中从开始到结束迭代1次,如果产品的周期在当前迭代中,则存储产品的折扣价格,否则为正常价格:

var periodCounter = [];

this.products.forEach(product => {
    for (i = range.start; i <= range.end; i ++) {
        if (!periodCounter[i]) {
            periodCounter[i] = 0;
        }

        if (i >= product.start && i <= product.end) {
            periodCounter[i] += product.def_amount;
        } else {
            periodCounter[i] += product.amount;
        }
    }
});
var periodCounter=[];
this.products.forEach(product=>{
对于(i=range.start;i=product.start&&i)您至少可以尝试一些东西,您知道您至少需要查看每个数组的开头和开头。在这之后,您可能应该做一些事情来获取有哪些范围,获取这些数字。您可以做一个开始,然后
var periodCounter = [];

this.products.forEach(product => {
    for (i = range.start; i <= range.end; i ++) {
        if (!periodCounter[i]) {
            periodCounter[i] = 0;
        }

        if (i >= product.start && i <= product.end) {
            periodCounter[i] += product.def_amount;
        } else {
            periodCounter[i] += product.amount;
        }
    }
});
var periods = [];
var periodStart = 0;
var periodEnd = 0;

for (i = range.start; i <= range.end; i ++) {
    if (i == range.start) {
        periodStart = i;
    } else {
        if (periodCounter[i] != periodCounter[i-1]) {
            periodEnd = i-1;
            periods.push({
                start: periodStart,
                end: periodEnd,
                amount: periodCounter[i-1]
            });
            periodStart = i;
        } 

        if (i == range.end) {
            periods.push({
                start: periodStart,
                end: i,
                amount: periodCounter[i]
            });
        }
    }
}