英文:
How would you guys do this mapping in JavaScript?
问题
以下是您提供的代码的翻译部分:
让我们假设我有一个如下的数组:
[100,2,3,4,200,35,42,300,4,4,4,6,7,400,2]
我想创建一个映射,如下所示:
{
{ key: 100,
value: 2
},
{ key: 100,
value: 3
}
{ key: 100,
value: 4
},
{ key: 200,
value: 35
},
{ key: 200,
value: 42
},
{ key: 300,
value: 4
},
{ key: 300,
value: 4
},
{ key: 300,
value: 4
},
{ key: 300,
value: 6
},
{ key: 300,
value: 7
},
{ key: 400,
value: 2
},
}
较大数组中的所有值都是具有一个或多个字段的对象。
我使用数字100、200、300、400来模拟只使用一个字段的值。其余的值当然包含多个字段。
我的目标是使用当前的标志(flag)创建映射元素,后面跟随的项目使用它。对于标志(flag)300,后续的元素是4,4,4,6,7。
这是我尝试过的代码:
let flagAndFollowingValues = new Map();
let j=0;
let followingElementsArray = [];
console.log(itemsToBeCheckedArray[j]);
for(let i=0; i<bigArray.length; i++){
if(Object.keys(bigArray[i]).length > 1)
{
followingElementsArray.push(bigArray[i]);
}else if(Object.keys(bigArray[i]).length === 1){
if(i===0){
j++;
flagAndFollowingValues.set(itemsToBeCheckedArray[j], followingElementsArray);
followingElementsArray=[];
}else{
flagAndFollowingValues.set(itemsToBeCheckedArray[j], followingElementsArray);
followingElementsArray=[];
}
}
}
希望这对您有所帮助。
英文:
Let's say I have an array as follows:
[100,2,3,4,200,35,42,300,4,4,4,6,7,400,2]
And I want to create a map, like so:
{
{ key: 100,
value: 2
},
{ key: 100,
value: 3
}
{ key: 100,
value: 4
},
{ key: 200,
value: 35
},
{ key: 200,
value: 42
},
{ key: 300,
value: 4
},
{ key: 300,
value: 4
},
{ key: 300,
value: 4
},
{ key: 300,
value: 6
},
{ key: 300,
value: 7
},
{ key: 400,
value: 2
},
}
All the values in the bigger array are objects which have one or more fields.
I simulated the values with only one field using numbers 100, 200, 300, 400. You can call them flags. The rest of them being values with more than 1 field, of course.
My goal is to create map elements using the current flag with the items that follow it. For flag 300, the following elements are 4,4,4,6,7.
Here is what I tried:
let flagAndFollowingValues = new Map();
let j=0;
let followingElementsArray = [];
console.log(itemsToBeCheckedArray[j]);
for(let i=0; i<bigArray.length; i++){
if(Object.keys(bigArray[i]).length > 1)
{
followingElementsArray.push(bigArray[i]);
}else if(Object.keys(bigArray[i]).length === 1){
if(i===0){
j++;
flagAndFollowingValues.set(itemsToBeCheckedArray[j], followingElementsArray);
followingElementsArray=[];
}else{
flagAndFollowingValues.set(itemsToBeCheckedArray[j], followingElementsArray);
followingElementsArray=[];
}
}
}
答案1
得分: 3
另一个使用单个标志而不是if/else/map的reduce()
选项
- 如果当前值大于
100
,将flag
设置为该值。 - 否则,向数组中添加一个新对象,
key
为flag
,value
为当前值。
const data = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2];
let flag = null;
const result = data.reduce((p, c, i) => {
if (c >= 100) {
flag = c;
} else {
p.push({ key: flag, value: c });
}
return p;
}, []);
console.log(result);
英文:
Another reduce()
option using a single flag instead of if/else/map's
- If the current value if larger then
100
, setflag
to that value - Otherwise, add a new object to the array, with
flag
askey
and the current value as thevalue
.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const data = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2];
let flag = null;
const result = data.reduce((p, c, i) => {
if (c >= 100) {
flag = c;
} else {
p.push({ key: flag, value: c });
}
return p;
}, []);
console.log(result);
<!-- end snippet -->
答案2
得分: 1
你可以通过将新的分组添加到结果数组的末尾来减少数据。
- 减少数据
- 如果值是键,则将其添加到累加器的末尾
- 否则,将当前值推送到累加器中的最后一个组中
- 将每个值组映射为一个带有其键的子值数组
const
input = [100, 2, 3, 4, 200, 35, 42, 300, 4, 4, 4, 6, 7, 400, 2],
processData = (arr, keyPredicate) => arr
.reduce((acc, n) => {
if (keyPredicate(n)) acc.push({ key: n, values: [] });
else acc[acc.length - 1].values.push(n);
return acc;
}, [])
.flatMap(({ key, values }) => values.map(value => ({ key, value }))),
processed = processData(input, n => n >= 100);
console.log(processed);
.as-console-wrapper { top: 0; max-height: 100% !important; }
英文:
You can reduce the data by adding new groups to the end of the resulting array.
- Reduce the data
- If the value is a key, add it to the end of the accumulator
- Else, push the current value to the last group in the accumulator
- Flat-map each group of values into a sub-array of values (with their key)
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const
input = [100, 2, 3, 4, 200, 35, 42, 300, 4, 4, 4, 6, 7, 400, 2],
processData = (arr, keyPredicate) => arr
.reduce((acc, n) => {
if (keyPredicate(n)) acc.push({ key: n, values: [] });
else acc[acc.length - 1].values.push(n);
return acc;
}, [])
.flatMap(({ key, values }) => values.map(value => ({ key, value }))),
processed = processData(input, n => n >= 100);
console.log(processed);
<!-- language: lang-css -->
.as-console-wrapper { top: 0; max-height: 100% !important; }
<!-- end snippet -->
答案3
得分: 0
首先创建一个地图逻辑,然后过滤掉错误的条目:
// 声明当前键是什么,以便在需要时保存
let currentKey = 0;
// 我们只想返回键和值
// 但如果数字能被100整除就不返回
let result = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2].map(
number => {
// 检查是键还是值
if (number % 100 === 0){
currentKey = number
return false;
}
return {key: currentKey, value: number}
}
);
// 删除错误的键
result = result.filter(entry => entry !== false)
console.log(result)
英文:
First create a map logic, then filter out false entries:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
// Declare what your current key is, so we can save it when needed
let currentKey = 0;
// We just want to return the key and value
// But not if the number is divisable by 100
let result = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2].map(
number => {
// Check if key or value
if (number % 100 === 0){
currentKey = number
return false;
}
return {key: currentKey, value: number}
}
);
// Remove false keys
result = result.filter(entry => entry !== false)
console.log(result)
<!-- end snippet -->
答案4
得分: 0
你提出的结构是无用的,你可能想要的是像这样的映射:
100 => [2, 3, 4]
200 => [35, 42]
等等
英文:
Your proposed structure is useless, what you probably want is a map like
100 => [ 2, 3, 4 ]
200 => [ 35, 42 ]
etc
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let a = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2]
let m = new Map()
let key = null
for (let x of a)
if (x % 100 === 0)
key = x
else if (m.has(key))
m.get(key).push(x)
else
m.set(key, [x])
console.log([...m])
<!-- end snippet -->
答案5
得分: 0
如果你的标志是100的倍数,那么它将起作用。
let flagObj = {};
const data = [100, 2, 3, 4, 200, 35, 42, 300, 4, 4, 4, 6, 7, 400, 2];
const res = data.reduce((acc, val, index) => {
let flag = val % 100;
if (flag === 0) {
flagObj[val] = val;
} else {
let allFlags = Object.keys(flagObj);
if (allFlags[allFlags.length - 1]) {
let key = allFlags[allFlags.length - 1]
acc.push({
key,
value: val,
});
}
}
return acc;
}, []);
console.log('result>>>>>>', res);
英文:
If your flag is a multiple of 100, in that case it will work
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let flagObj = {};
const data = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2];
const res = data.reduce((acc, val, index)=> {
let flag = val % 100;
if(flag === 0 ){
flagObj[val] = val;
} else{
let allFlags = Object.keys(flagObj);
if(allFlags[allFlags.length-1]){
let key = allFlags[allFlags.length -1]
acc.push({
key,
value: val,
});
}
}
return acc;
},[]);
console.log('result>>>>>', res);
<!-- end snippet -->
答案6
得分: 0
以下是您要翻译的内容:
如果我们有一个splitWhenever
函数,它根据谓词的结果将数组拆分成连续值的子数组,我们可以简单地编写如下代码:
const process = (xs) =>
splitWhenever (n => n % 100 == 0) (xs)
.flatMap (([key, ...vals]) => vals .map (value => ({key, value})))
这样的splitWhenever
函数相当通用,在其他情况下也很有用,可以放入我们的个人工具包以在需要时重用。我们可以像这样使用它:
const isOdd = (n => n % 2 === 1)
splitWhenever (isOdd) ([5, 6, 8, 12, 3, 8, 10, 17, 24, 5, 7, 14, 28])
//=> [[5, 6, 8, 12], [3, 8, 10], [17, 24], [5], [7, 14, 28]]
或者我们可以扩展它,以允许谓词检查当前值与前一个值是否相同,就像这样:
const sameDecade = (x, y) => Math .floor (x / 10) !== Math .floor (y / 10)
splitWhenever (sameDecade) ([23, 27, 22, 45, 42, 57, 51, 12, 16, 25, 27, 21])
//=> [[23, 27, 22], [45, 42], [57, 51], [12, 16], [25, 27, 21]]
当然,这样的函数可以像这样使用:
// const isFlag = (n) => n > 99)
// const isFlag = (n) => [100, 200, 300, 400, 500, 1000] .includes (n)
const isFlag = (n) => n % 100 == 0
splitWhenever (isFlag) ([100, 2, 3, 4, 200, 35, 42, 300, 4, 4, 4, 6, 7, 400, 2])
//=> [[100, 2, 3, 4], [200, 35, 42], [300, 4, 4, 4, 6, 7], [400, 2]]
(请注意isFlag
的各种版本。问题并没有清楚地说明如何确定标志值。)
我有一个相当经常使用的splitWhenever
函数。我们可以像这样使用它:
英文:
If we had a splitWhenever
function that split an array into subarrays of consecutive values based on the result of a predicate, we could write this simply as
const process = (xs) =>
splitWhenever (n => n % 100 == 0) (xs)
.flatMap (([key, ...vals]) => vals .map (value => ({key, value})))
Such a splitWhenever
is fairly generic and useful in other situations, and it might go in our personal toolkit to be reused as necessary. We might use it like this:
const isOdd = (n => n % 2 === 1)
splitWhenever (isOdd) ([5, 6, 8, 12, 3, 8, 10, 17, 24, 5, 7, 14, 28])
//=> [[5, 6, 8, 12], [3, 8, 10], [17, 24], [5], [7, 14, 28]]
Or we might extend it to allow the predicate to check the current value against the previous one, like this:
const sameDecade = (x, y) => Math .floor (x / 10) !== Math .floor (y / 10)
splitWhenever (sameDecade) ([23, 27, 22, 45, 42, 57, 51, 12, 16, 25, 27, 21])
//=> [[23, 27, 22], [45, 42], [57, 51], [12, 16], [25, 27, 21]]
And of course such a function could be used like this:
// const isFlag = (n) => n > 99)
// const isFlag = (n) => [100, 200, 300, 400, 500, 1000] .includes (n)
const isFlag = (n) => n % 100 == 0
splitWhenever (isFlag) ([100, 2, 3, 4, 200, 35, 42, 300, 4, 4, 4, 6, 7, 400, 2])
//=> [[100, 2, 3, 4], [200, 35, 42], [300, 4, 4, 4, 6, 7], [400, 2]]
(Note the various versions of isFlag
. The question doesn't make it clear how you determine the flag values.)
I have such a splitWhenever
I used fairly often. We can use it like this:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const splitWhenever = (pred) => (xs) =>
xs .length == 0 ? [] : xs .slice (1) .reduce (
((xss, x, i) => pred (x, xs[i])
? [...xss, [x]]
: [...xss .slice (0, -1), [... xss [xss .length - 1], x]]
), [[xs [0]]]
)
const process = (xs) =>
splitWhenever (n => n % 100 == 0) (xs)
.flatMap (([key, ...vals]) => vals .map (value => ({key, value})))
console .log (
process ([100, 2, 3, 4, 200, 35, 42, 300, 4, 4, 4, 6, 7, 400, 2])
)
<!-- language: lang-css -->
.as-console-wrapper {max-height: 100% !important; top: 0}
<!-- end snippet -->
答案7
得分: 0
You can use Array#forEach
和 Array#push
方法如下所示:
const input = [100, 2, 3, 4, 200, 35, 42, 300, 4, 4, 4, 6, 7, 400, 2],
output = [];
let key = 0;
input.forEach(value => {
if (value < 100) {
output.push({ key, value });
} else {
key = value;
}
});
console.log(output);
英文:
You can use Array#forEach
and Array#push
methods as follows:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const
input = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2],
output = [];
let
key = 0;
input.forEach(value => {
if( value < 100 ) {
output.push({key, value});
} else {
key = value;
}
});
console.log( output );
<!-- end snippet -->
答案8
得分: -1
我猜这段代码是不言自明的。只需迭代数组,要么获取一个新键,要么将值添加到当前键。
const source = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2];
const mapped = [];
let key;
for(const value of source){
if(value % 100 === 0){
key = value;
continue;
}
mapped.push({key,value});
}
console.log(mapped);
英文:
I guess the code is self-explanatory. Just iterate the array and either get a new key or add a value to the current key.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const source = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2];
const mapped = [];
let key;
for(const value of source){
if(value % 100 === 0){
key = value;
continue;
}
mapped.push({key,value});
}
console.log(mapped);
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论