Object.keys、concat(Array)、assign(form,obj)、map()、forEach(fun)

这篇博客详细介绍了JavaScript中五个常用的方法:Object.keys()用于获取对象属性组成的数组;concat()用于连接并返回数组副本;assign()用于合并多个对象;map()创建新数组,其结果是调用提供的函数处理后的数组元素;以及forEach()遍历数组并执行函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、在实际开发中,我们有时需要知道对象的所有属性,原生js给我们提供了一个很好的方法:Object.keys(),该方法返回一个数组
  • 传入对象,返回属性名
var obj = {'a':'123','b':'345'};
console.log(Object.keys(obj));  //['a','b']

var obj1 = { 100: "a", 2: "b", 7: "c"};
console.log(Object.keys(obj1)); // console: ["2", "7", "100"]

var obj2 = Object.create({}, { getFoo : { value : function () { return this.foo } } });
obj2.foo = 1;
console.log(Object.keys(obj2)); // console: ["foo"]
  • 传入字符串,返回索引
var str = 'ab1234';
console.log(Object.keys(obj));  //[0,1,2,3,4,5]
  • 构造函数 返回空数组或者属性名
    function Pasta(name, age, gender) {
            this.name = name;
            this.age = age;
            this.gender = gender;
            this.toString = function () {
                    return (this.name + ", " + this.age + ", " + this.gender);
            }
    }

    console.log(Object.keys(Pasta)); //console: []

    var spaghetti = new Pasta("Tom", 20, "male");
    console.log(Object.keys(spaghetti)); //console: ["name", "age", "gender", "toString"]
  • 数组 返回索引
  • var arr = ["a", "b", "c"]; console.log(Object.keys(arr)); // console: ["0", "1", "2"]   

二、concat(Array)方法

    concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。
    array1.concat([item1[, item2[, . . . [, itemN]]]])
    说明
    concat 方法返回一个 Array 对象,其中包含了 array1 和提供的任意其他项目的连接。
    要加的项目(item1 … itemN)会按照从左到右的顺序添加到数组。如果某一项为数组,那么添加其内容到 array1 的末尾。如果该项目不是数组,就将其作为单个的数组元素添加到数组的末尾。
    以下为从源数组复制元素到结果数组:
    对于从正被连接到新数组的数组中复制的对象参数,复制后仍然指向相同的对象。不论新数组和源数组中哪一个有改变,都将引起另一个的改变。
    对于连接到新数组的数值或字符串,只复制其值。一个数组中值有改变并不影响另一个数组中的值。

复制代码
//concat()把两个或者多个数组链接在一起,但是不改变已经存在的数组
//而是返回一个链接之后的新数组
var a = [1,2,3];
a.concat([4,5]);
console.log(a);
//此处输出为 [1, 2, 3]

var a = [1,2,3];
a = a.concat([4,5]);
console.log(a);
//此处输出为 [1, 2, 3 ,4 ,5]
复制代码


三、assign(form,obj)


    问题情况:将2个或2个以上对象(object{....})中的属性进行合并,即最后合并为一个object{.....}传递给后端。

    问题场景:多页表单数据的一同提交

    解决办法:Object.assign 方法

     Object.assign(form, obj)----->Object.assign(目标对象, 被合并的对象)
复制代码
<script>
    let form = {name: 'liming', sex: '男'};
    let obj = {class: '一班', age: 15};
    console.log('before', form);
    Object.assign(form, obj);
    console.log('after', form);
</script>
复制代码


四、map()

map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

map() 方法按照原始数组元素顺序依次处理元素。

注意: map() 不会对空数组进行检测。

注意: map() 不会改变原始数组。


array.map(function(currentValue,index,arr), thisValue)
参数描述
function(currentValue, index,arr)必须。函数,数组中的每个元素都会执行这个函数
函数参数:
参数描述
currentValue必须。当前元素的值
index可选。当期元素的索引值
arr可选。当期元素属于的数组对象
thisValue可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。
如果省略了 thisValue ,"this" 的值为 "undefined"


    map()方法将调用的数组的每个元素传递给指定的函数,并返回一个数组,它包含该函数的返回值。

       传递给map()的函数的调用方式和传递给forEach()的函数的调用方式一样。但传递给map()的函数应该有返回值。注意:map()返回的是新数组:它不修改调用的数组。如果是稀疏数组,返回的也是相同方式的稀疏数组:它具有相同的长度,相同的缺失元素。

      举个例子:

      要求:为数组 arr 中的每个元素求二次方。不要直接修改数组 arr,结果返回新的数组 

      实现:

  1. function square(arr){  
  2.     return arr.map(function(item){  
  3.         return item*item;});  
  4. }  
  5. var arr=[1, 2, 3, 4];  
  6. console.log(square(arr));  
      结果:[1,4,9,16]

五、[].forEach(function(value,index,array){})

forEach是ES5中操作数组的一种方法,主要功能是遍历数组,例如:

  

1
2
var arr = [1,2,3,4];
arr.forEach(alert);

 等价于:

1
2
3
4
var arr = [1, 2, 3, 4];
for (var k = 0, length = arr.length; k < length; k++) {
 alert(array[k]);
}

 forEach方法中的function回调有三个参数:第一个参数是遍历的数组内容,第二个参数是对应的数组索引,第三个参数是数组本身

因此:

  

1
2
3
4
5
[].forEach(function(value,index,array){
 
    //code something
 
  });

  

等价于:

 

1
2
3
4
5
$.each([],function(index,value,array){
 
   //code something
 
 })

  

写一个例子;

1
2
3
4
5
6
var arr = [1,2,3,4];
arr.forEach(function(value,index,array){
    array[index] == value;    //结果为true
    sum+=value;  
    });
console.log(sum);    //结果为 10



import { Request, Response } from "express"; import { Item } from "../ts/tabuwithweight/Item"; import { Instance } from "../ts/tabuwithweight/Instance"; import { multiply, doArr, removeFrom2DArrayByProperty, stackCargoAll, stackCargo, stackCargoAll2, stackCargo2, stackCargoFullHeight } from '../ts/util' import { Solution } from "../ts/tabuwithweight/Solution"; import { Worker } from 'worker_threads'; import { PlaceItem } from "../ts/tabuwithweight/PlaceItem"; import * as os from 'os'; // 引入 Node.js 的 os 模块 import { db } from "../app"; function intersection(arr1: any[], arr2: any[]) { let arr3:any[] = [] let arr4:any[] = [] arr1.forEach(item => { item.split('-').forEach((it:any) => { arr3.push(it) }) }) arr2.forEach(item => { item.split('-').forEach((it:any) => { arr4.push(it) }) }) //返回arr3中包含几个arr4中的元素 return arr3.filter(item => arr4.indexOf(item) !== -1); } async function loop2(car:carType, car2:carType, goods:itemType[], goods2: itemType[], his: any[], prev: any[]): Promise<any>{ goods.sort((a, b) => { //货物先按面积排序,相同面积的再按高度排序 return a.id - b.id || multiply(b.length, b.width) - multiply(a.length, a.width) || b.depth - a.depth }) goods2.sort((a, b) => { //货物先按面积排序,相同面积的再按高度排序 return a.id - b.id || multiply(b.length, b.width) - multiply(a.length, a.width) || b.depth - a.depth }) // let res: resType<itemType> = doArr(goods, car) // let res2: resType<itemType> = doArr(goods2, car) let groups:itemType[][] = [] let groups1:itemType[][] = [] let groups2:itemType[][] = [] // console.log('prev',prev) prev.forEach((it: any)=>{ // console.log(it) let g:itemType[] = [] let g2:itemType[] = [] it.split('-').forEach((it3: any, i3: number)=>{ let obj = { depth: goods.find((it2: any)=>{return it3 == it2.id}).depth, width: goods.find((it2: any)=>{return it3 == it2.id}).width, length: goods.find((it2: any)=>{return it3 == it2.id}).length, weight: goods.find((it2: any)=>{return it3 == it2.id}).weight, boxNumber: goods.find((it2: any)=>{return it3 == it2.id}).boxNumber, packageType: goods.find((it2: any)=>{return it3 == it2.id}).packageType, packageName: goods.find((it2: any)=>{return it3 == it2.id}).packageName, id: it3, warehouseName: goods.find((it2: any)=>{return it3 == it2.id}).warehouseName, allowedRotation: goods.find((it2: any)=>{return it3 == it2.id}).allowedRotation, pc: goods.find((it2: any)=>{return it3 == it2.id}).pc, } g.push(obj) if(obj.pc != 2){ g2.push(obj) } }) groups.push(g) groups1.push(g) groups2.push(g2) }) // let groups = stackCargoAll2(car.innerDepth, goods.concat(goods2)) // let groups1 = stackCargo2(car.innerDepth, goods.concat(goods2)) // let groups2 = stackCargo2(car.innerDepth, goods) // let groups1 = prev // let groups2 = prev let batch1GoodsId = groups1.flat().map(it=>it.id) let batch2GoodsId = groups2.flat().map(it=>it.id) // console.log(batch1GoodsId) // console.log(batch1GoodsId.length) let batch1Goods:itemType[] = [] let batch2Goods:itemType[] = [] goods.concat(goods2).forEach((it:any)=>{ if(batch1GoodsId.includes(it.id)){ batch1Goods.push(it) } }) goods.forEach((it:any)=>{ if(batch2GoodsId.includes(it.id)){ batch2Goods.push(it) } }) let nofull:nofullType = {} //不同高度叠放 let nosamedifang:any[] = [] let nofullall:nofullType = {} let nopack = [] let boxes:any[] = [] let nofullarr: {id?:string,extra?: number, carindex?: number}[] = [] let itemList: Item[] = [] let itemList2: Item[] = [] let instance = new Instance(); let instance2 = new Instance(); let allNames:string[] = [] let allNames2:string[] = [] groups.forEach(it=>{ let ids = `` let tmp = it.map(it2=>{ return it2.id }) let weight = 0 it.forEach(it2=>{ weight += it2.weight }) ids = tmp.join('-') // console.log(ids) itemList.push(new Item(ids, multiply(it[0].length, 100), multiply(it[0].width, 100), weight, it[0].depth, it[0].boxNumber)) allNames.push(ids) }) groups2.forEach(it=>{ let ids = `` let tmp = it.map(it2=>{ return it2.id }) let weight = 0 it.forEach(it2=>{ weight += it2.weight }) ids = tmp.join('-') itemList2.push(new Item(ids, multiply(it[0].length, 100), multiply(it[0].width, 100), weight, it[0].depth, it[0].boxNumber)) allNames2.push(ids) }) instance.setW(car2.innerLength) instance.setH(car2.innerWidth) instance.setRotateEnable(false) instance.setItemList(itemList) instance2.setW(car2.innerLength) instance2.setH(car2.innerWidth) instance2.setRotateEnable(false) instance2.setItemList(itemList2) function isContain(arr:string[], str:string){ return arr.some(it=>{ return str.startsWith(it,0) }) } let ress:Solution[] = [] let ress2:Solution[] = [] // 获取CPU的核心数 let cpus = os.cpus(); let coreCount = cpus.length; //总循环次数 let loopTime = 2 //每个线程执行的循环次数 let pre = Math.floor(loopTime / coreCount)?Math.floor(loopTime / coreCount):1 // let coreHalf = Math.floor(coreCount/2)?Math.floor(coreCount/2):1 let coreHalf = 1 let workdata = { innerLength:car2.innerLength, innerWidth:car2.innerWidth, maxWeight:car2.maxWeight, groups:groups, goods: goods.concat(goods2), batch2GoodsId:batch2GoodsId.map(it => it.toString()), loopTime:pre==loopTime?Math.floor(loopTime / 2):pre } // console.log('innerLength',workdata.innerLength) // console.log('innerWidth',workdata.innerWidth) console.log('maxWeight',car2.maxWeight) let prom = [] for (let index = 0; index < coreHalf; index++) { prom.push(getWorkerResult(workdata)) } for (let index = 0; index < coreHalf; index++) { prom.push(getWorkerResult2(workdata)) } let proRes = await Promise.all(prom) proRes.forEach((it3:any, i3:number)=>{ it3.forEach((it2:any)=>{ let placeItemLists: PlaceItem[] = [] it2.placeItemList.forEach((it: any)=>{ let pla:PlaceItem = new PlaceItem(it.name,it.x,it.y,it.w,it.h,it.isRotate,it.weight) placeItemLists.push(pla) }) let sol: Solution = new Solution(placeItemLists, it2.totalS, it2.rate, car2.innerLength, car2.innerWidth) if(i3 < coreHalf){ ress.push(sol) }else{ ress2.push(sol) } }) }) ress.sort((a, b) => { let arr1 = a.getPlaceItemList().map(it => it.getName()); let arr2 = b.getPlaceItemList().map(it => it.getName()); let intersectionLengthA = intersection(arr1, batch2GoodsId.map(it => it.toString())).length; let intersectionLengthB = intersection(arr2, batch2GoodsId.map(it => it.toString())).length; // 先比较交集长度 if (intersectionLengthA !== intersectionLengthB) { return intersectionLengthB - intersectionLengthA; // 从高到低排序 } else { // 如果交集长度相同,则比较 rate return b.getRate() * 1000 - a.getRate() * 1000; // 从高到低排序 } }) ress2.sort((a, b) => { let arr1 = a.getPlaceItemList().map(it => it.getName()); let arr2 = b.getPlaceItemList().map(it => it.getName()); let intersectionLengthA = intersection(arr1, batch2GoodsId.map(it => it.toString())).length; let intersectionLengthB = intersection(arr2, batch2GoodsId.map(it => it.toString())).length; // 先比较交集长度 if (intersectionLengthA !== intersectionLengthB) { return intersectionLengthB - intersectionLengthA; // 从高到低排序 } else { // 如果交集长度相同,则比较 rate return b.getRate() * 1000 - a.getRate() * 1000; // 从高到低排序 } }) let maxNum = intersection(ress[0].getPlaceItemList().map(it=>it.getName()), batch2GoodsId.map(it=>{return it.toString()})).length let maxNum2 = intersection(ress2[0].getPlaceItemList().map(it=>it.getName()), batch2GoodsId.map(it=>{return it.toString()})).length // let maxNum = ress[0].getRate() // let maxNum2 = ress2[0].getRate() // console.log('maxNum',maxNum) // console.log('batch2GoodsId',batch2GoodsId.map(it=>{return it.toString()})) // console.log('maxNum2',maxNum2) if(maxNum2 > maxNum){ ress = ress2 maxNum = maxNum2 // console.log(11) } if(maxNum2 == maxNum){ if(ress[0].getRate() < ress2[0].getRate()){ ress = ress2 maxNum = maxNum2 } } let maxRate = ress[0].getRate() // let maxList = ress let maxList = ress.filter(it=>{ return (intersection(it.getPlaceItemList().map(it2=>it2.getName()), batch2GoodsId.map(it=>{return it.toString()})).length === maxNum) }) maxList.sort((a, b)=>{ return b.getRate()*1000 - a.getRate()*1000 }) let lens:number[] = [] let vs:number[] = [] //冒泡排序 按体积排序 function vsort(a:Solution, b:Solution): number{ //体积 let v1 = 0 let v2 = 0 a.getPlaceItemList().forEach((it2:any)=>{ //单个物品体积 let tv:number = 0 //通过 it2.getName().split('-').forEach((it3:any)=>{ let o = goods.concat(goods2).find(it4=>{ return Number(it3) == it4.id }) tv += multiply(multiply(o.width,o.length),o.depth) }) v1 += tv }) b.getPlaceItemList().forEach((it2:any)=>{ //单个物品体积 let tv:number = 0 //通过 it2.getName().split('-').forEach((it3:any)=>{ let o = goods.concat(goods2).find(it4=>{ return Number(it3) == it4.id }) tv += multiply(multiply(o.width,o.length),o.depth) }) v2 += tv }) if(v2 != v1){ return v2 - v1 }else{ return b.getRate()*1000 - a.getRate()*1000 } } maxList.sort(vsort) let solution = maxList[0] // ress.sort((a, b) => { // // 如果交集长度相同,则比较 rate // return b.getRate() * 1000 - a.getRate() * 1000; // 从高到低排序 // }) // ress2.sort((a, b) => { // // 如果交集长度相同,则比较 rate // return b.getRate() * 1000 - a.getRate() * 1000; // 从高到低排序 // }) // let maxNum = ress[0].getRate() // let maxNum2 = ress2[0].getRate() // if(maxNum2 > maxNum){ // ress = ress2 // maxNum = maxNum2 // // console.log(11) // } // if(maxNum2 == maxNum){ // if(ress[0].getRate() < ress2[0].getRate()){ // ress = ress2 // maxNum = maxNum2 // } // } // let maxRate = ress[0].getRate() // let maxList = ress // maxList.sort((a, b)=>{ // return b.getRate()*1000 - a.getRate()*1000 // }) // let lens:number[] = [] // let vs:number[] = [] // //冒泡排序 按体积排序 // function vsort(a:Solution, b:Solution): number{ // //体积 // let v1 = 0 // let v2 = 0 // a.getPlaceItemList().forEach((it2:any)=>{ // //单个物品体积 // let tv:number = 0 // //通过 // it2.getName().split('-').forEach((it3:any)=>{ // let o = goods.concat(goods2).find(it4=>{ // return Number(it3) == it4.id // }) // tv += multiply(multiply(o.width,o.length),o.depth) // }) // v1 += tv // }) // b.getPlaceItemList().forEach((it2:any)=>{ // //单个物品体积 // let tv:number = 0 // //通过 // it2.getName().split('-').forEach((it3:any)=>{ // let o = goods.concat(goods2).find(it4=>{ // return Number(it3) == it4.id // }) // tv += multiply(multiply(o.width,o.length),o.depth) // }) // v2 += tv // }) // if(v2 != v1){ // return v2 - v1 // }else{ // return b.getRate()*1000 - a.getRate()*1000 // } // } // maxList.sort(vsort) // let solution = maxList[0] // console.log('solutionx',solution.getXOffset()) // console.log('solutiony',solution.getYOffset()) let nopacked = JSON.parse(JSON.stringify(itemList)) // console.log('solution',solution.getPlaceItemList().map(it=>{return it.getName()})) // console.log('nopacked',nopacked.map((it:any)=>{return it.name})) let finalResult:any[] = [] for(let i = nopacked.length - 1; i >= 0; i--) { if(solution.getPlaceItemList().find(delItem => delItem.getName().split('-')[0] === nopacked[i].name.split('-')[0])) { let waitFix = solution.getPlaceItemList().find(delItem => delItem.getName().split('-')[0] === nopacked[i].name.split('-')[0]) if(waitFix){ waitFix.setName(nopacked[i].name) } nopacked.splice(i, 1); } } // console.log('nopacked.length2',nopacked.length) solution.getPlaceItemList().forEach((it, i)=>{ let flag = it.getName().split('-').every(it2=>{ let pc = goods.concat(goods2).find(it3=>{return it2 == it3.id.toString()}).weight return pc == 2 }) if(flag){ let l = goods2.find((it2: any)=>{return it.getName().split('-')[0] == it2.id}).length let w = goods2.find((it2: any)=>{return it.getName().split('-')[0] == it2.id}).width let d = 0 it.getName().split('-').forEach(it2=>{ d += goods2.find((it3: any)=>{return it2 == it3.id.toString()}).depth }) //查询nopacked中有没有同样尺寸的 for (let index = 0; index < nopacked.length; index++) { let it2 = nopacked[index]; let l2 = goods.concat(goods2).find((it3: any)=>{return it2.name.split('-')[0] == it3.id}).length let w2 = goods.concat(goods2).find((it3: any)=>{return it2.name.split('-')[0] == it3.id}).width if(l2 == l && w2 == w){ let d2 = 0 it2.name.split('-').forEach((it3: any)=>{ d2 += goods.concat(goods2).find((it4: any)=>{return it3 == it4.id.toString()}).depth }) if(d2 > d){ let na = JSON.parse(JSON.stringify(it.getName())) it.setName(it2.name) nopacked[index].name = na; } } } } }) let soluv = 0 solution.getPlaceItemList().forEach((it2:any)=>{ //单个物品体积 let tv:number = 0 //通过 it2.getName().split('-').forEach((it3:any)=>{ let o = goods.concat(goods2).find(it4=>{ return Number(it3) == it4.id }) tv += multiply(multiply(o.width,o.length),o.depth) }) soluv += tv }) let rate3d = soluv / (car.innerLength*car.innerDepth*car.innerWidth) solution.setRate3d(rate3d) //上一次装箱结果 his.push(solution) let all:any[] = [] all = goods.concat(goods2) // console.log(nopacked.length) if(nopacked.length > 0){ let copyItemList = JSON.parse(JSON.stringify(itemList)) let nextboxes:itemType[] = [] let prevarr: any[] = [] // console.log(nopacked) nopacked.forEach((it: any)=>{ // console.log(it) it.name.split('-').forEach((it3: any, i3: number)=>{ let obj = { depth: all.find((it2: any)=>{return it3 == it2.id}).depth, width: all.find((it2: any)=>{return it3 == it2.id}).width, length: all.find((it2: any)=>{return it3 == it2.id}).length, weight: all.find((it2: any)=>{return it3 == it2.id}).weight, boxNumber: all.find((it2: any)=>{return it3 == it2.id}).boxNumber, id: it3, packageType: goods.find((it2: any)=>{return it3 == it2.id}).packageType, packageName: goods.find((it2: any)=>{return it3 == it2.id}).packageName, warehouseName: all.find((it2: any)=>{return it3 == it2.id}).warehouseName, allowedRotation: all.find((it2: any)=>{return it3 == it2.id}).allowedRotation, } nextboxes.push(obj) }) prevarr.push(it.name) }) return new Promise<any[]>(async (resolve, reject) => { const resss = await loop2(car, car2, nextboxes, [], his, prevarr) resolve(resss) }) }else{ return new Promise<any[]>((resolve, reject) => { resolve(his) }) } } export let index = async (req: Request, res: Response): Promise<void> => { res.type('html'); // res.render('index', { title: 'Express' }); res.render('limitlayer', { title: 'Express' }); // res.render("index", { title: "Express" }); }; export let index2 = async (req: Request, res: Response): Promise<void> => { res.type('html'); // res.render('index', { title: 'Express' }); res.render('limitlayer2', { title: 'Express' }); // res.render("index", { title: "Express" }); }; async function getWorkerResult(data: any){ return new Promise((resolve, reject)=>{ let worker = new Worker('./src/controllers/worker5.mjs'); worker.on('message', (event) => { // console.log('rece',event); resolve(event) worker.terminate(); // 终止Worker线程 }) worker.postMessage({ type: 'DATA', data: data }); }) } async function getWorkerResult2(data: any){ return new Promise((resolve, reject)=>{ let worker = new Worker('./src/controllers/worker6.mjs'); worker.on('message', (event) => { // console.log('rece',event); resolve(event) worker.terminate(); // 终止Worker线程 }) worker.postMessage({ type: 'DATA', data: data }); }) } export let two3 = async (req: Request, resp: Response): Promise<void> => { try { console.log('two3') //车辆信息 let car: carType = JSON.parse(req.body.car) //复制一份不影响原始车辆信息 let car2: carType = JSON.parse(JSON.stringify(car)) let car3: carType = JSON.parse(JSON.stringify(car)) car2.rotate = Object.hasOwnProperty.call(car2, 'rotate') ? Boolean(Number(car.rotate)) : true car2.innerDepth = multiply(car2.innerDepth , 100) car2.innerLength = multiply(car2.innerLength , 100) car2.innerWidth = multiply(car2.innerWidth , 100) car2.outerDepth = multiply(car2.outerDepth , 100) car2.outerLength = multiply(car2.outerLength , 100) car2.outerWidth = multiply(car2.outerWidth , 100) car2.emptyWeight = multiply(car2.emptyWeight , 100) car2.maxWeight = multiply(car2.maxWeight,1) car3.innerDepth = multiply(car3.innerDepth , 1000) car3.innerLength = multiply(car3.innerLength , 1000) car3.innerWidth = multiply(car3.innerWidth , 1000) car3.outerDepth = multiply(car3.outerDepth , 1000) car3.outerLength = multiply(car3.outerLength , 1000) car3.outerWidth = multiply(car3.outerWidth , 1000) car3.emptyWeight = multiply(car3.emptyWeight , 1000) car3.maxWeight = multiply(car3.maxWeight,1) //货物信息 let goods: itemType[] = JSON.parse(req.body.boxes) let goods2: itemType[] = JSON.parse(req.body.boxes2) goods.sort((a, b) => { //货物先按面积排序,相同面积的再按高度排序 return a.id - b.id || multiply(b.length, b.width) - multiply(a.length, a.width) || b.depth - a.depth }) goods2.sort((a, b) => { //货物先按面积排序,相同面积的再按高度排序 return a.id - b.id || multiply(b.length, b.width) - multiply(a.length, a.width) || b.depth - a.depth }) // let res: resType<itemType> = doArr(goods, car) // let res2: resType<itemType> = doArr(goods2, car) let tmp = stackCargoFullHeight(car.innerDepth, goods.concat(goods2)) let groups = tmp.res let groups1 = tmp.res let groups2 = tmp.res1 let batch1GoodsId = groups1.flat().map(it=>it.id) // console.log(batch1GoodsId) let batch2GoodsId = groups2.flat().map(it=>it.id) let batch1Goods:itemType[] = [] let batch2Goods:itemType[] = [] goods.concat(goods2).forEach((it:any)=>{ if(batch1GoodsId.includes(it.id)){ batch1Goods.push(it) } }) goods.forEach((it:any)=>{ if(batch2GoodsId.includes(it.id)){ batch2Goods.push(it) } }) let nofull:nofullType = {} //不同高度叠放 let nosamedifang:any[] = [] let nofullall:nofullType = {} let nopack = [] let boxes:any[] = [] let nofullarr: {id?:string,extra?: number, carindex?: number}[] = [] let itemList: Item[] = [] let itemList2: Item[] = [] let instance = new Instance(); let instance2 = new Instance(); let allNames:string[] = [] let allNames2:string[] = [] groups.forEach(it=>{ let ids = `` let tmp = it.map(it2=>{ return it2.id }) ids = tmp.join('-') // console.log(ids) itemList.push(new Item(ids, multiply(it[0].length, 100), multiply(it[0].width, 100), it[0].weight, it[0].depth, it[0].boxNumber)) allNames.push(ids) }) groups2.forEach(it=>{ let ids = `` let tmp = it.map(it2=>{ return it2.id }) ids = tmp.join('-') itemList2.push(new Item(ids, multiply(it[0].length, 100), multiply(it[0].width, 100), it[0].weight, it[0].depth, it[0].boxNumber)) allNames2.push(ids) }) // console.log(groups) instance.setW(car2.innerLength) instance.setH(car2.innerWidth) instance.setRotateEnable(false) instance.setItemList(itemList) instance2.setW(car2.innerLength) instance2.setH(car2.innerWidth) instance2.setRotateEnable(false) instance2.setItemList(itemList2) function isContain(arr:string[], str:string){ return arr.some(it=>{ return str.startsWith(it,0) }) } let ress:Solution[] = [] let ress2:Solution[] = [] // 获取CPU的核心数 let cpus = os.cpus(); let coreCount = cpus.length; //总循环次数 let loopTime = 2 //每个线程执行的循环次数 let pre = Math.floor(loopTime / coreCount)?Math.floor(loopTime / coreCount):1 let coreHalf = 1 let workdata = { innerLength:car2.innerLength, innerWidth:car2.innerWidth, maxWeight:car2.maxWeight, groups:groups, rotate:car2.rotate, goods: goods.concat(goods2), batch2GoodsId:batch2GoodsId.map(it => it.toString()), loopTime:pre==loopTime?Math.floor(loopTime / 2):pre } let prom = [] for (let index = 0; index < coreHalf; index++) { prom.push(getWorkerResult(workdata)) } for (let index = 0; index < coreHalf; index++) { prom.push(getWorkerResult2(workdata)) } let proRes = await Promise.all(prom) proRes.forEach((it3:any, i3:number)=>{ it3.forEach((it2:any)=>{ let placeItemLists: PlaceItem[] = [] it2.placeItemList.forEach((it: any)=>{ let pla:PlaceItem = new PlaceItem(it.name,it.x,it.y,it.w,it.h,it.isRotate,it.weight) placeItemLists.push(pla) }) let sol: Solution = new Solution(placeItemLists, it2.totalS, it2.rate, car2.innerLength, car2.innerWidth) if(i3 < coreHalf){ ress.push(sol) }else{ ress2.push(sol) } }) }) ress.sort((a, b) => { let arr1 = a.getPlaceItemList().map(it => it.getName()); let arr2 = b.getPlaceItemList().map(it => it.getName()); let intersectionLengthA = intersection(arr1, batch2GoodsId.map(it => it.toString())).length; let intersectionLengthB = intersection(arr2, batch2GoodsId.map(it => it.toString())).length; // 先比较交集长度 if (intersectionLengthA !== intersectionLengthB) { return intersectionLengthB - intersectionLengthA; // 从高到低排序 } else { // 如果交集长度相同,则比较 rate return b.getRate() * 1000 - a.getRate() * 1000; // 从高到低排序 } }) ress2.sort((a, b) => { let arr1 = a.getPlaceItemList().map(it => it.getName()); let arr2 = b.getPlaceItemList().map(it => it.getName()); let intersectionLengthA = intersection(arr1, batch2GoodsId.map(it => it.toString())).length; let intersectionLengthB = intersection(arr2, batch2GoodsId.map(it => it.toString())).length; // 先比较交集长度 if (intersectionLengthA !== intersectionLengthB) { return intersectionLengthB - intersectionLengthA; // 从高到低排序 } else { // 如果交集长度相同,则比较 rate return b.getRate() * 1000 - a.getRate() * 1000; // 从高到低排序 } }) let maxNum = intersection(ress[0].getPlaceItemList().map(it=>it.getName()), batch2GoodsId.map(it=>{return it.toString()})).length let maxNum2 = intersection(ress2[0].getPlaceItemList().map(it=>it.getName()), batch2GoodsId.map(it=>{return it.toString()})).length // let maxNum = ress[0].getRate() // let maxNum2 = ress2[0].getRate() if(maxNum2 > maxNum){ ress = ress2 maxNum = maxNum2 // console.log(11) } if(maxNum2 == maxNum){ if(ress[0].getRate() < ress2[0].getRate()){ ress = ress2 maxNum = maxNum2 } } let maxRate = ress[0].getRate() let maxList = ress.filter(it=>{ return (intersection(it.getPlaceItemList().map(it2=>it2.getName()), batch2GoodsId.map(it=>{return it.toString()})).length === maxNum) }) maxList.sort((a, b)=>{ return b.getRate()*1000 - a.getRate()*1000 }) let lens:number[] = [] let vs:number[] = [] //冒泡排序 按体积排序 function vsort(a:Solution, b:Solution): number{ //体积 let v1 = 0 let v2 = 0 a.getPlaceItemList().forEach((it2:any)=>{ //单个物品体积 let tv:number = 0 //通过 it2.getName().split('-').forEach((it3:any)=>{ let o = goods.concat(goods2).find(it4=>{ return Number(it3) == it4.id }) tv += multiply(multiply(o.width,o.length),o.depth) }) v1 += tv }) b.getPlaceItemList().forEach((it2:any)=>{ //单个物品体积 let tv:number = 0 //通过 it2.getName().split('-').forEach((it3:any)=>{ let o = goods.concat(goods2).find(it4=>{ return Number(it3) == it4.id }) tv += multiply(multiply(o.width,o.length),o.depth) }) v2 += tv }) if(v2 != v1){ return v2 - v1 }else{ return b.getRate()*1000 - a.getRate()*1000 } } maxList.sort(vsort) let solution = maxList[0] let nopacked = JSON.parse(JSON.stringify(itemList)) let finalResult:any[] = [] for(let i = nopacked.length - 1; i >= 0; i--) { if(solution.getPlaceItemList().find(delItem => delItem.getName().split('-')[0] === nopacked[i].name.split('-')[0])) { let waitFix = solution.getPlaceItemList().find(delItem => delItem.getName().split('-')[0] === nopacked[i].name.split('-')[0]) if(waitFix){ waitFix.setName(nopacked[i].name) } nopacked.splice(i, 1); } } solution.getPlaceItemList().forEach((it, i)=>{ let flag = it.getName().split('-').every(it2=>{ let pc = goods.concat(goods2).find(it3=>{return it2 == it3.id.toString()}).weight return pc == 2 }) if(flag){ let l = goods2.find((it2: any)=>{return it.getName().split('-')[0] == it2.id}).length let w = goods2.find((it2: any)=>{return it.getName().split('-')[0] == it2.id}).width let d = 0 it.getName().split('-').forEach(it2=>{ d += goods2.find((it3: any)=>{return it2 == it3.id.toString()}).depth }) //查询nopacked中有没有同样尺寸的 for (let index = 0; index < nopacked.length; index++) { let it2 = nopacked[index]; let l2 = goods.concat(goods2).find((it3: any)=>{return it2.name.split('-')[0] == it3.id}).length let w2 = goods.concat(goods2).find((it3: any)=>{return it2.name.split('-')[0] == it3.id}).width if(l2 == l && w2 == w){ let d2 = 0 it2.name.split('-').forEach((it3: any)=>{ d2 += goods.concat(goods2).find((it4: any)=>{return it3 == it4.id.toString()}).depth }) if(d2 > d){ let na = JSON.parse(JSON.stringify(it.getName())) it.setName(it2.name) nopacked[index].name = na; } } } } }) let soluv = 0 solution.getPlaceItemList().forEach((it2:any)=>{ //单个物品体积 let tv:number = 0 //通过 it2.getName().split('-').forEach((it3:any)=>{ let o = goods.concat(goods2).find(it4=>{ return Number(it3) == it4.id }) tv += multiply(multiply(o.width,o.length),o.depth) }) soluv += tv }) let rate3d = soluv / (car.innerLength*car.innerDepth*car.innerWidth) solution.setRate3d(rate3d) let all:any[] = [] all = goods.concat(goods2) if(nopacked.length > 0){ let copyItemList = JSON.parse(JSON.stringify(itemList)) let nextboxes:itemType[] = [] let prev: any[] = [] // console.log(nopacked) nopacked.forEach((it: any)=>{ // console.log(it) it.name.split('-').forEach((it3: any, i3: number)=>{ let obj = { depth: all.find((it2: any)=>{return it3 == it2.id}).depth, width: all.find((it2: any)=>{return it3 == it2.id}).width, length: all.find((it2: any)=>{return it3 == it2.id}).length, weight: all.find((it2: any)=>{return it3 == it2.id}).weight, boxNumber: all.find((it2: any)=>{return it3 == it2.id}).boxNumber, id: it3, packageType: goods.find((it2: any)=>{return it3 == it2.id}).packageType, packageName: goods.find((it2: any)=>{return it3 == it2.id}).packageName, warehouseName: all.find((it2: any)=>{return it3 == it2.id}).warehouseName, allowedRotation: all.find((it2: any)=>{return it3 == it2.id}).allowedRotation, } nextboxes.push(obj) }) prev.push(it.name) }) finalResult = await loop2(car, car2, nextboxes, [], [solution], prev) }else{ finalResult = [solution] } let result:any = [] finalResult.forEach((it2: any)=>{ let obj:any = {} obj.box = car3 let copyPlace = JSON.parse(JSON.stringify(it2.getPlaceItemList())) obj.items = copyPlace result.push(obj) }) result.forEach((it2: any)=>{ it2.items.forEach((it: any)=>{ let length = Math.floor(it.w / 100 * 1000) it.width = Math.floor(it.h / 100 * 1000) it.height = Math.floor(it.h / 100 * 1000) it.depth = Math.floor(all.find(it3=>{return it3.id == it.name.split('-')[0]}).depth * it.name.split('-').length * 1000) it.length = length //互换xy let temp = it.x it.x = it.y it.y = temp it.x = Math.floor(it.x / 100 * 1000) it.y = Math.floor(it.y / 100 * 1000) it.z = 0 let param = {} Object.assign(param,it,{description:it.name}) it.item = param }) }) nofullarr.forEach(it=>{ result.forEach((it2:any,i2:number)=>{ let flag = it2.items.some((it3:any)=>{ if(it3.name.indexOf(it.id) !== -1){ return true } }) if(flag){ it.carindex = i2 } }) }) let copyFinalResult = JSON.parse(JSON.stringify(finalResult)) let copyNofullarr = JSON.parse(JSON.stringify(nofullarr)) function changePos(cari: number): void { let firstCarNofull = nofullarr.filter((it)=>{return it.carindex == cari}) firstCarNofull.forEach(it=>{ //第一车中 不满的货物 let w = all.find((it2)=>{return it2.id == it.id.split('-')[0]}).width let l = all.find((it2)=>{return it2.id == it.id.split('-')[0]}).length let d = all.find((it2)=>{return it2.id == it.id.split('-')[0]}).depth let fi = copyFinalResult[0].placeItemList.findIndex((it2: any)=>{ return it2.name == it.id}) let searchIndex = -1 //倒叙循环finalResult,搜索后方车辆有没有 长宽高和第一车不满的货物一样的 for(let i = copyFinalResult.length - 1; i >= cari + 1; i--){ //如果结果中有wld和第一车一样的 交换位置 searchIndex = copyFinalResult[i].placeItemList.findIndex((it2: any)=>{ let w2 = all.find((it3)=>{return it3.id == it2.name.split('-')[0]}).width let l2 = all.find((it3)=>{return it3.id == it2.name.split('-')[0]}).length let d2 = all.find((it3)=>{return it3.id == it2.name.split('-')[0]}).depth return w == w2 && l == l2 && d == d2 }) if(searchIndex != -1){ //将第一车placeItemList数组中的第fi个元素的name和第i车placeItemList的第searchIndex个元素的name互换 let temp = copyFinalResult[cari].placeItemList[fi].name copyFinalResult[cari].placeItemList[fi].name = copyFinalResult[i].placeItemList[searchIndex].name copyFinalResult[i].placeItemList[searchIndex].name = temp copyNofullarr.find((it2: any)=>{return it2.id == it.id}).carindex = i break } } }) } // for (let index = 0; index < finalResult.length - 1; index++) { // changePos(index) // } result = [] copyFinalResult.forEach((it2: any)=>{ let obj:any = {} obj.box = car3 let copyPlace = JSON.parse(JSON.stringify(it2.placeItemList)) obj.items = copyPlace result.push(obj) }) result.forEach((it2: any)=>{ it2.items.forEach((it: any)=>{ let length = Math.floor(it.w / 100 * 1000) it.width = Math.floor(it.h / 100 * 1000) it.height = Math.floor(it.h / 100 * 1000) it.depth = Math.floor(all.find(it3=>{return it3.id == it.name.split('-')[0]}).depth * it.name.split('-').length * 1000) it.length = length //互换xy let temp = it.x it.x = it.y it.y = temp it.x = Math.floor(it.x / 100 * 1000) it.y = Math.floor(it.y / 100 * 1000) it.z = 0 let param = {} Object.assign(param,it,{description:it.name}) it.item = param }) }) let freeArr: any[] = [] copyFinalResult.forEach((it: any, i: number)=>{ let po: any = {} let boxes:any[] = [] it.placeItemList.forEach((it2: any)=>{ let o: any = {} o.x = it2.x o.y = it2.y o.width = it2.w o.height = it2.h boxes.push(o) }) po.carindex = i freeArr.push(po) }) resp.json({ code:200, car:car, boxes:goods.concat(goods2), nofullarr:copyNofullarr, message:'装箱成功', success:true, finalResult: copyFinalResult, changeFinalResult: copyFinalResult, freeArr:nosamedifang, data:result }) } catch (error) { console.log(error) resp.json({ code:500, message:'装箱失败', success:false, }) } }; export let index4 = async (req: Request, res: Response): Promise<void> => { res.type('html'); // res.render('index', { title: 'Express' }); res.render('limithistory', { title: 'Express' }); // res.render("index", { title: "Express" }); };
最新发布
06-26
<think>好的,我现在要帮用户弄清楚Reflect.ownKeysObject.keys的区别。首先,我需要回顾一下自己之前了解的知识,然后结合用户提供的引用内容来整理出一个清晰的回答。 首先,用户提到了四个引用,其中引用[2]和引用[3]详细比较了两者的区别。引用[2]指出,Object.keys返回的是可枚举的自有属性,不包括Symbol属性和原型链上的属性。而Reflect.ownKeys则包括所有自有属性,无论是可枚举、不可枚举还是Symbol属性。引用[3]进一步说明Reflect.ownKeys是全面的,包含不可枚举和Symbol属性,而引用[4]则用例子展示了Object.keys无法获取不可枚举属性,而Reflect.ownKeys可以。 接下来,我需要将这些信息结构化,确保覆盖以下几点: 1. 可枚举性:Object.keys只返回可枚举的属性,Reflect.ownKeys包括不可枚举的。 2. Symbol属性:Object.keys不包括Symbol,而Reflect.ownKeys包含。 3. 原型属性:两者都不包括原型链上的属性,但这点可能需要特别说明,避免用户误解。 4. 返回结果的结构:比如引用[2]中的示例代码,显示Object.keys返回["a"],而Reflect.ownKeys返回["a", "name", Symbol()]。 然后,我需要考虑用户可能的疑问,例如为什么会有这样的区别,或者实际应用场景。比如,当需要获取对象的所有自有属性时(如深拷贝、序列化),Reflect.ownKeys更合适,而Object.keys适用于普通遍历。 同时,用户的问题可能涉及到性能或其他方法(如Object.getOwnPropertyNames),但根据引用内容,用户主要关注的是两者的区别,所以需要集中在这四点。另外,用户提供的引用中没有提到性能问题,所以暂时不需要涉及。 需要确保回答准确,每个点都有引用支持。例如,在解释可枚举性时,引用[2]和引用[4]的例子可以证明这一点。Symbol属性部分则引用[2]和[3]的示例。 最后,生成相关问题时要围绕主题,比如应用场景、其他相关方法的比较,或者如何处理不可枚举属性等。这样用户如果有进一步的问题,可以继续探索。</think>### Reflect.ownKeysObject.keys 的区别 在 JavaScript 中,`Reflect.ownKeys` 和 `Object.keys` 都用于获取对象的属性集合,但两者在行为上有以下核心差异: 1. **可枚举性要求** - `Object.keys()` 仅返回对象自身的**可枚举属性**的键名[^2][^4]。 - `Reflect.ownKeys()` 返回对象自身的**所有属性**的键名,包括不可枚举属性和 Symbol 属性[^2][^3]。 2. **Symbol 属性的处理** - `Object.keys()` 会忽略 Symbol 类型的属性键[^3]。 - `Reflect.ownKeys()` 包含所有 Symbol 类型的属性键[^2]。 3. **返回值范围** - `Object.keys()` 的返回值是 `Object.getOwnPropertyNames()` 的子集(仅可枚举属性)[^1]。 - `Reflect.ownKeys()` 的返回值等同于 `Object.getOwnPropertyNames().concat(Object.getOwnPropertySymbols())`[^1]。 4. **应用场景** - `Object.keys()` 适用于需要遍历对象可见属性的场景(如常规数据处理)。 - `Reflect.ownKeys()` 适用于需要完整操作对象属性的场景(如深拷贝、元编程)。 --- #### 示例对比 通过代码示例可直观看出差异: ```javascript const symbolKey = Symbol('key'); const obj = { [symbolKey]: 'value', a: 'a' }; Object.defineProperty(obj, 'name', { value: 'sunny', enumerable: false }); console.log(Object.keys(obj)); // ["a"] console.log(Reflect.ownKeys(obj)); // ["a", "name", Symbol(key)] ``` - `Object.keys` 仅返回可枚举的 `a`。 - `Reflect.ownKeys` 额外包含不可枚举的 `name` 和 Symbol 属性[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值