如何在JavaScript中执行这个映射?

huangapple go评论81阅读模式
英文:

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
   },


}

较大数组中的所有值都是具有一个或多个字段的对象

我使用数字100200300400来模拟只使用一个字段的值其余的值当然包含多个字段

我的目标是使用当前的标志flag创建映射元素后面跟随的项目使用它对于标志flag300后续的元素是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&lt;bigArray.length; i++){
if(Object.keys(bigArray[i]).length &gt; 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()选项

  1. 如果当前值大于100,将flag设置为该值。
  2. 否则,向数组中添加一个新对象,keyflagvalue为当前值。
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


  1. If the current value if larger then 100, set flag to that value
  2. Otherwise, add a new object to the array, with flag as key and the current value as the value.

<!-- 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) =&gt; {
if (c &gt;= 100) {
flag = c;
} else {
p.push({ key: flag, value: c });         
}
return p;
}, []);
console.log(result);

<!-- end snippet -->

答案2

得分: 1

你可以通过将新的分组添加到结果数组的末尾来减少数据。

  1. 减少数据
    1. 如果值是键,则将其添加到累加器的末尾
    2. 否则,将当前值推送到累加器中的最后一个组中
  2. 将每个值组映射为一个带有其键的子值数组
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.

  1. Reduce the data
    1. If the value is a key, add it to the end of the accumulator
    2. Else, push the current value to the last group in the accumulator
  2. 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) =&gt; arr
.reduce((acc, n) =&gt; {
if (keyPredicate(n)) acc.push({ key: n, values: [] });
else acc[acc.length - 1].values.push(n);
return acc;
}, [])
.flatMap(({ key, values }) =&gt; values.map(value =&gt; ({ key, value }))),
processed = processData(input, n =&gt; n &gt;= 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 =&gt; {
// 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 =&gt; 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 =&gt; [ 2, 3, 4 ]
200 =&gt; [ 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)=&gt; {
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(&#39;result&gt;&gt;&gt;&gt;&gt;&#39;, 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) =&gt; 
  splitWhenever (n =&gt; n % 100 == 0) (xs) 
    .flatMap (([key, ...vals]) =&gt; vals .map (value =&gt; ({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 =&gt; n % 2 === 1)
splitWhenever (isOdd) ([5, 6, 8, 12, 3, 8, 10, 17, 24, 5, 7, 14, 28])
    //=&gt; [[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) =&gt; Math .floor (x / 10) !== Math .floor (y / 10) 
splitWhenever (sameDecade) ([23, 27, 22, 45, 42, 57, 51, 12, 16, 25, 27, 21])
    //=&gt; [[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) =&gt; n &gt; 99)
// const isFlag = (n) =&gt; [100, 200, 300, 400, 500, 1000] .includes (n)
const isFlag = (n) =&gt; n % 100 == 0
splitWhenever (isFlag) ([100, 2, 3, 4, 200, 35, 42, 300, 4, 4, 4, 6, 7, 400, 2])
    //=&gt; [[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) =&gt; (xs) =&gt;
xs .length == 0 ? [] : xs .slice (1) .reduce (
((xss, x, i) =&gt; pred (x, xs[i]) 
? [...xss, [x]] 
: [...xss .slice (0, -1), [... xss [xss .length - 1], x]]
), [[xs [0]]]
)
const process = (xs) =&gt; 
splitWhenever (n =&gt; n % 100 == 0) (xs) 
.flatMap (([key, ...vals]) =&gt; vals .map (value =&gt; ({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#forEachArray#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 =&gt; {
if( value &lt; 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 -->

huangapple
  • 本文由 发表于 2023年5月22日 20:03:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76306004.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定